diff --git a/R/characterization-incidence.R b/R/characterization-incidence.R
index b3076a33..3e01a8b3 100644
--- a/R/characterization-incidence.R
+++ b/R/characterization-incidence.R
@@ -1,6 +1,6 @@
-# @file characterization-timeToEvent.R
+# @file characterization-incidence.R
#
-# Copyright 2022 Observational Health Data Sciences and Informatics
+# Copyright 2023 Observational Health Data Sciences and Informatics
#
# This file is part of OhdsiShinyModules
#
@@ -17,6 +17,92 @@
# limitations under the License.
+as_ggplot <- function(x){
+ # Open null device to avoid blank page before plot------
+ # see cowplot:::as_grob.ggplot
+ null_device <- base::getOption(
+ "ggpubr.null_device",
+ default = cowplot::pdf_null_device
+ )
+ cur_dev <- grDevices::dev.cur()
+ # Open null device to avoid blank page before plot
+ null_device(width = 6, height = 6)
+ null_dev <- grDevices::dev.cur()
+ on.exit({
+ grDevices::dev.off(null_dev)
+ if (cur_dev > 1) grDevices::dev.set(cur_dev)
+ })
+ # Convert to ggplot-------------
+ cowplot::ggdraw() +
+ cowplot::draw_grob(grid::grobTree(x))
+}
+
+# Custom function that takes a ggplotly figure and its facets as arguments.
+# The upper x-values for each domain is set programmatically, but you can adjust
+# the look of the figure by adjusting the width of the facet domain and the
+# corresponding annotations labels through the domain_offset variable
+fixfacets <- function(figure, facets, domain_offset){
+
+ fig <- figure
+
+ # split x ranges from 0 to 1 into
+ # intervals corresponding to number of facets
+ # xHi = highest x for shape
+ xHi <- seq(0, 1, len = length(facets)+1)
+ xHi <- xHi[2:length(xHi)]
+
+ xOs <- domain_offset
+
+ # Shape manipulations, identified by dark grey backround: "rgba(217,217,217,1)"
+ # structure: p$x$layout$shapes[[2]]$
+ shp <- fig$x$layout$shapes
+ j <- 1
+ for (i in seq_along(shp)){
+ if (shp[[i]]$fillcolor=="rgba(217,217,217,1)" & (!is.na(shp[[i]]$fillcolor))){
+ #$x$layout$shapes[[i]]$fillcolor <- 'rgba(0,0,255,0.5)' # optionally change color for each label shape
+ fig$x$layout$shapes[[i]]$x1 <- xHi[j]
+ fig$x$layout$shapes[[i]]$x0 <- (xHi[j] - xOs)
+ #fig$x$layout$shapes[[i]]$y <- -0.05
+ j<-j+1
+ }
+ }
+
+ # annotation manipulations, identified by label name
+ # structure: p$x$layout$annotations[[2]]
+ ann <- fig$x$layout$annotations
+ annos <- facets
+ j <- 1
+ for (i in seq_along(ann)){
+ if (ann[[i]]$text %in% annos){
+ # but each annotation between high and low x,
+ # and set adjustment to center
+ fig$x$layout$annotations[[i]]$x <- (((xHi[j]-xOs)+xHi[j])/2)
+ fig$x$layout$annotations[[i]]$xanchor <- 'center'
+ #print(fig$x$layout$annotations[[i]]$y)
+ #fig$x$layout$annotations[[i]]$y <- -0.05
+ j<-j+1
+ }
+ }
+
+ # domain manipulations
+ # set high and low x for each facet domain
+ xax <- names(fig$x$layout)
+ j <- 1
+ for (i in seq_along(xax)){
+ if (!is.na(pmatch('xaxis', xax[i]))){
+ #print(p[['x']][['layout']][[lot[i]]][['domain']][2])
+ fig[['x']][['layout']][[xax[i]]][['domain']][2] <- xHi[j]
+ fig[['x']][['layout']][[xax[i]]][['domain']][1] <- xHi[j] - xOs
+ j<-j+1
+ }
+ }
+
+ return(fig)
+}
+
+
+
+
#' The module viewer for exploring incidence results
#'
#' @details
@@ -31,14 +117,7 @@
characterizationIncidenceViewer <- function(id) {
ns <- shiny::NS(id)
shiny::div(
- #shinydashboard::box(
- # collapsible = TRUE,
- # collapsed = TRUE,
- # title = "Incidence Rates",
- # width = "100%",
- # shiny::htmlTemplate(system.file("characterization-www", "help-incidenceRate.html", package = utils::packageName()))
- # ),
-
+
infoHelperViewer(
id = "helper",
helpLocation= system.file("characterization-www", "help-incidenceRate.html", package = utils::packageName())
@@ -63,7 +142,23 @@ characterizationIncidenceViewer <- function(id) {
),
shiny::tabPanel(
title = "Incidence Rate Plots",
- #code to view plot here
+ shiny::tabsetPanel(
+ type = 'pills',
+ id = ns('incPlotPanel'),
+ shiny::tabPanel(
+ title = "Custom Plot",
+ shinycssloaders::withSpinner(
+ plotly::plotlyOutput(ns('incidencePlot'),
+ height = "1600px",
+ width = "90%")
+ ),
+ shiny::plotOutput(ns('incidencePlotLegend'),
+ width="100%",
+ height="300px"
+ )
+
+ )
+ )
)
)
)
@@ -93,497 +188,829 @@ characterizationIncidenceServer <- function(
) {
shiny::moduleServer(
id,
+ #' Title
+ #'
+ #' @param input
+ #' @param output
+ #' @param session
+ #'
+ #' @return
+ #' @export
+ #'
+ #' @examples
function(input, output, session) {
- cohorts <- getTargetOutcomes(
- connectionHandler,
- resultDatabaseSettings
- )
- # input selection component
- inputSelected <- inputSelectionServer(
- id = "input-selection",
- inputSettingList = list(
- createInputSetting(
- rowNumber = 1,
- columnWidth = 6,
- varName = 'targetIds',
- uiFunction = 'shinyWidgets::pickerInput',
- uiInputs = list(
- label = 'Target: ',
- choices = cohorts$targetIds,
- selected = cohorts$targetIds[1],
- multiple = T,
- options = shinyWidgets::pickerOptions(
- actionsBox = TRUE,
- liveSearch = TRUE,
- size = 10,
- liveSearchStyle = "contains",
- liveSearchPlaceholder = "Type here to search",
- virtualScroll = 50
+ ## ns <- session$ns
+
+ options <- getIncidenceOptions( # written using getTargetOutcomes
+ connectionHandler,
+ resultDatabaseSettings
+ )
+
+ # input selection component
+ inputSelected <- inputSelectionServer(
+ id = "input-selection",
+ inputSettingList = list(
+ createInputSetting(
+ rowNumber = 1,
+ columnWidth = 12,
+ varName = 'firsttext',
+ inputReturn = F,
+ uiFunction = 'shiny::div',
+ uiInputs = list(
+ "Select Your Results",
+ style = "font-weight: bold; font-size: 20px; text-align: center; margin-bottom: 20px;"
)
- )
- ),
- createInputSetting(
- rowNumber = 1,
- columnWidth = 6,
- varName = 'outcomeIds',
- uiFunction = 'shinyWidgets::pickerInput',
- uiInputs = list(
- label = 'Outcome: ',
- choices = cohorts$outcomeIds,
- selected = cohorts$outcomeIds[1],
- multiple = T,
- options = shinyWidgets::pickerOptions(
- actionsBox = TRUE,
- liveSearch = TRUE,
- size = 10,
- liveSearchStyle = "contains",
- liveSearchPlaceholder = "Type here to search",
- virtualScroll = 50
+ ),
+ createInputSetting(
+ rowNumber = 2,
+ columnWidth = 6,
+ varName = 'targetIds',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Target: ',
+ choices = options$targetIds,
+ selected = options$targetIds[1],
+ multiple = T,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+ createInputSetting(
+ rowNumber = 2,
+ columnWidth = 6,
+ varName = 'outcomeIds',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Outcome: ',
+ choices = options$outcomeIds,
+ selected = options$outcomeIds[1],
+ multiple = T,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ # third row
+ createInputSetting(
+ rowNumber = 3,
+ columnWidth = 4,
+ varName = 'incidenceRateAgeFilter',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ collapse = T,
+ uiInputs = list(
+ label = 'Filter By Age: ',
+ choices = options$ageGroupName,
+ selected = options$ageGroupName,
+ multiple = T,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+
+ createInputSetting(
+ rowNumber = 3,
+ columnWidth = 4,
+ varName = 'incidenceRateGenderFilter',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ collapse = T,
+ uiInputs = list(
+ label = 'Filter By Sex: ',
+ choices = options$genderName,
+ selected = options$genderName,
+ multiple = T,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ createInputSetting(
+ rowNumber = 3,
+ columnWidth = 4,
+ varName = 'incidenceRateCalendarFilter',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ collapse = T,
+ uiInputs = list(
+ label = 'Filter By Start Year: ',
+ choices = options$startYear,
+ selected = options$startYear,
+ multiple = T,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ # 4th row text
+ createInputSetting(
+ rowNumber = 4,
+ columnWidth = 12,
+ varName = 'secondtext',
+ inputReturn = F,
+ uiFunction = 'shiny::div',
+ uiInputs = list(
+ "Configure Your Plot",
+ style = "font-weight: bold; font-size: 20px; text-align: center; margin-bottom: 20px; margin-top: 20px; "
+ )
+ ),
+
+ # plotting settings 5th row
+
+ createInputSetting(
+ rowNumber = 5,
+ columnWidth = 3,
+ varName = 'plotYAxis',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Y Axis (Numeric) ',
+ choices = options$irPlotNumericChoices,
+ selected = "incidenceRateP100py",
+ multiple = F,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ createInputSetting(
+ rowNumber = 5,
+ columnWidth = 3,
+ varName = 'plotXAxis',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'X Axis (Categorical) ',
+ choices = options$irPlotCategoricalChoices,
+ selected = "startYear",
+ multiple = F,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ createInputSetting(
+ rowNumber = 5,
+ columnWidth = 3,
+ varName = 'plotXTrellis',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Row Trellis (Categorical) ',
+ choices = options$irPlotCategoricalChoices,
+ selected = "targetName",
+ multiple = F,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ createInputSetting(
+ rowNumber = 5,
+ columnWidth = 3,
+ varName = 'plotYTrellis',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Column Trellis (Categorical)',
+ choices = options$irPlotCategoricalChoices,
+ selected = "outcomeName",
+ multiple = F,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ # row 6
+
+ createInputSetting(
+ rowNumber = 6,
+ columnWidth = 4,
+ varName = 'plotColor',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Color (Categorical)',
+ choices = options$irPlotCategoricalChoices,
+ selected = "cdmSourceAbbreviation",
+ multiple = F,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+ createInputSetting(
+ rowNumber = 6,
+ columnWidth = 4,
+ varName = 'plotSize',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Plot Point Size (Numeric)',
+ choices = options$irPlotNumericChoices,
+ selected = "outcomes",
+ multiple = F,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
)
+ ),
+ createInputSetting(
+ rowNumber = 6,
+ columnWidth = 4,
+ varName = 'plotShape',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Plot Point Shape (Categorical)',
+ choices = options$irPlotCategoricalChoices,
+ selected = "genderName",
+ multiple = F,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ # row 7
+
+ createInputSetting(
+ rowNumber = 7,
+ columnWidth = 8,
+ varName = 'incidenceRateTarFilter',
+ uiFunction = 'shinyWidgets::pickerInput',
+ updateFunction = 'shinyWidgets::updatePickerInput',
+ uiInputs = list(
+ label = 'Select Time at risk (TAR)',
+ choices = options$tar,
+ selected = options$tar[1],
+ multiple = F,
+ options = shinyWidgets::pickerOptions(
+ actionsBox = TRUE,
+ liveSearch = TRUE,
+ size = 10,
+ dropupAuto = TRUE,
+ liveSearchStyle = "contains",
+ liveSearchPlaceholder = "Type here to search",
+ virtualScroll = 50
+ )
+ )
+ ),
+
+ createInputSetting(
+ rowNumber = 7,
+ columnWidth = 4,
+ varName = 'irYscaleFixed',
+ uiFunction = 'shiny::checkboxInput',
+ uiInputs = list(
+ label = "Use same y-axis scale across plots?"
+ )
+ )
+
+
+
)
- )
)
- )
-
-
-
- # allDataDownload <- shiny::reactiveVal(data.frame())
- # selectedInputs <- shiny::reactiveVal()
- # output$IRinputsText <- shiny::renderUI(selectedInputs())
-
- #if generate is pushed, extract the data
- allData <- shiny::reactive({
- getIncidenceData(targetIds = inputSelected()$targetIds,
- outcomeIds = inputSelected()$outcomeIds,
- connectionHandler = connectionHandler,
- resultDatabaseSettings = resultDatabaseSettings
- ) %>%
- dplyr::relocate(.data$tar, .before = .data$outcomes) %>%
- dplyr::mutate(dplyr::across(dplyr::where(is.numeric), round, 4))
- })
-
- create_select_input <- function(values, name) {
- shiny::tags$select(
- # Set to undefined to clear the filter
- onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # "All" has an empty value to clear the filter, and is the default option
- shiny::tags$option(value = "", "All"),
- lapply(unique(values), shiny::tags$option),
- "aria-label" = sprintf("Filter %s", name),
- style = "width: 100%; height: 28px;"
- )
- }
- js_code <- "
- // Custom range filter with value label
- function rangeFilter(column, state) {
- // Get min and max values from raw table data
- let min = Infinity;
- let max = 0;
- state.data.forEach(function(row) {
- const value = row[column.id];
- if (value < min) {
- min = Math.floor(value);
- } else if (value > max) {
- max = Math.ceil(value);
+ filteredData <- shiny::reactive(
+ {
+ if (is.null(inputSelected()$targetIds) |
+ is.null(inputSelected()$outcomeIds)) {
+ return(data.frame())
}
- });
-
- const filterValue = column.filterValue || min;
- const input = React.createElement('input', {
- type: 'range',
- value: filterValue,
- min: min,
- max: max,
- onChange: function(event) {
- // Set to undefined to clear the filter
- column.setFilter(event.target.value || undefined);
- },
- style: { width: '100%', marginRight: '8px' },
- 'aria-label': 'Filter ' + column.name
- });
-
- return React.createElement(
- 'div',
- { style: { display: 'flex', alignItems: 'center', height: '100%' } },
- [input, filterValue]
- );
- }
-
- // Filter method that filters numeric columns by minimum value
- function filterMinValue(rows, columnId, filterValue) {
- return rows.filter(function(row) {
- return row.values[columnId] >= filterValue;
- });
- }
- "
+
+ getIncidenceData(targetIds = inputSelected()$targetIds,
+ outcomeIds = inputSelected()$outcomeIds,
+ connectionHandler = connectionHandler,
+ resultDatabaseSettings = resultDatabaseSettings
+ ) %>%
+ dplyr::relocate(tar, .before = outcomes) %>%
+ dplyr::mutate(incidenceProportionP100p = as.numeric(incidenceProportionP100p),
+ incidenceRateP100py = as.numeric(incidenceRateP100py),
+ dplyr::across(dplyr::where(is.numeric), round, 4),
+ targetIdShort = paste("C", targetCohortDefinitionId, sep = ":"),
+ outcomeIdShort = paste("C", outcomeCohortDefinitionId, sep = ":")) %>%
+ dplyr::filter(ageGroupName %in% inputSelected()$incidenceRateAgeFilter &
+ genderName %in% inputSelected()$incidenceRateGenderFilter &
+ startYear %in% inputSelected()$incidenceRateCalendarFilter
+ )
+ }
+ )
+
+
+ incidenceColList <- ParallelLogger::loadSettingsFromJson(
+ system.file("components-columnInformation",
+ "characterization-incidence-colDefs.json",
+ package = "OhdsiShinyModules"
+ )
+ )
+ ##class(incidenceColList$genderName$filterMethod) <- "JS_EVAL"
+ renderIrTable <- shiny::reactive(
+ {
+ filteredData()
+ }
+ )
+ resultTableServer(
+ id = "incidenceRateTable",
+ df = renderIrTable,
+ selectedCols = c("cdmSourceAbbreviation", "targetName", "outcomeName",
+ "ageGroupName", "genderName", "startYear", "tar", "outcomes",
+ "incidenceProportionP100p", "incidenceRateP100py"),
+ sortedCols = c("ageGroupName", "genderName", "startYear", "incidenceRateP100py"),
+ elementId = "incidence-select",
+ colDefsInput = incidenceColList,
+ downloadedFileName = "incidenceRateTable-"
+ )
- #read in custom column name colDef list from rds file, generated by
- #heplers-componentsCreateCustomColDefList.R
+ #ir plots - TODO edit to reactive
+ renderIrPlot <- shiny::reactive(
+ {
+ if (is.null(inputSelected()$targetIds) |
+ is.null(inputSelected()$outcomeIds)) {
+ return(data.frame())
+ }
+
+ plotData <- filteredData() %>%
+ dplyr::filter(tar %in% inputSelected()$incidenceRateTarFilter)
+
+ # Take the specific tar value you want to plot
+ tar_value <- unique(plotData$tar)[1]
+
+ # Create a column for the tooltip text
+ plotData$tooltip <- with(plotData, paste(
+ "Incidence Rate:", incidenceRateP100py, "
",
+ "Incidence Proportion:", incidenceProportionP100p, "
",
+ "Outcome ID:", outcomeIdShort, "
",
+ "Outcome Name:", outcomeName, "
",
+ "Target ID:", targetIdShort, "
",
+ "Target Name:", targetName, "
",
+ "Data Source:", cdmSourceAbbreviation, "
",
+ "Calendar Year:", startYear, "
",
+ "Age Group:", ageGroupName, "
",
+ "Sex:", genderName, "
",
+ "Clean Window:", cleanWindow, "
",
+ "Persons at Risk:", personsAtRisk, "
",
+ "Person Days:", personDays, "
",
+ "Outcomes:", outcomes
+ ))
+
+
+ # Check if color, size, shape, and trellis variables are selected, and set aesthetics accordingly
+ color_aesthetic <- NULL
+ size_aesthetic <- NULL
+ shape_aesthetic <- NULL
+ trellis_aesthetic_x <- NULL
+ trellis_aesthetic_y <- NULL
+
+ if (inputSelected()$plotColor == "Target Cohort" | inputSelected()$plotColor == "Outcome Cohort") {
+ color_aesthetic <- if (inputSelected()$plotColor == "Target Cohort") {
+ dplyr::vars(targetIdShort)
+ } else if (inputSelected()$plotColor == "Outcome Cohort") {
+ dplyr::vars(outcomeIdShort)
+ }
+ }
+
+ if (inputSelected()$plotShape == "Target Cohort" | inputSelected()$plotShape == "Outcome Cohort") {
+ shape_aesthetic <- if (inputSelected()$plotShape == "Target Cohort") {
+ dplyr::vars(targetIdShort)
+ } else if (inputSelected()$plotShape == "Outcome Cohort") {
+ dplyr::vars(outcomeIdShort)
+ }
+ }
+
+ max_length <- max(nchar(unique(inputSelected()$plotXAxis)))
+
+ if (inputSelected()$plotXTrellis != inputSelected()$plotYTrellis){
+
+ # Create the base plot with conditional aesthetics
+ base_plot <- ggplot2::ggplot(
+ data = plotData,
+ ggplot2::aes(x = .data[[inputSelected()$plotXAxis]],
+ y = .data[[inputSelected()$plotYAxis]],
+ shape = if(inputSelected()$plotShape != "None" & inputSelected()$plotShape != "Target Cohort" &
+ inputSelected()$plotShape != "Outcome Cohort") .data[[inputSelected()$plotShape]]
+ else shape_aesthetic,
+ color = if(inputSelected()$plotColor != "None" & inputSelected()$plotColor != "Target Cohort" &
+ inputSelected()$plotColor != "Outcome Cohort") .data[[inputSelected()$plotColor]]
+ else color_aesthetic,
+ text = tooltip
+ )
+ ) +
+ ggplot2::geom_point(ggplot2::aes(size = if(inputSelected()$plotSize != "None") .data[[inputSelected()$plotSize]] else NULL,
+ alpha = 0.6)
+ )
+
+ # Rotate x-axis labels if the maximum length is greater than 10
+ if (max_length > 10) {
+ base_plot <- base_plot +
+ ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 45, hjust = 1))
+ }
+
+ # Add trellising if it's not NULL
+ if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(.data[[inputSelected()$plotXTrellis]]),
+ cols = vars(.data[[inputSelected()$plotYTrellis]]),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis=="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(targetIdShort),
+ cols = vars(.data[[inputSelected()$plotYTrellis]]),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis=="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(outcomeIdShort),
+ cols = vars(.data[[inputSelected()$plotYTrellis]]),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis=="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(.data[[inputSelected()$plotXTrellis]]),
+ cols = vars(targetIdShort),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis=="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(.data[[inputSelected()$plotXTrellis]]),
+ cols = vars(outcomeIdShort),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis=="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis=="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(targetIdShort),
+ cols = vars(targetIdShort),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis=="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis=="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(targetIdShort),
+ cols = vars(outcomeIdShort),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis=="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis=="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(outcomeIdShort),
+ cols = vars(targetIdShort),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis=="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis=="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(outcomeIdShort),
+ cols = vars(outcomeIdShort),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis=="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis=="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = NULL,
+ cols = vars(outcomeIdShort),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis=="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis=="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = NULL,
+ cols = vars(targetIdShort),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis=="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis!="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = NULL,
+ cols = vars(.data[[inputSelected()$plotYTrellis]]),
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis=="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(.data[[inputSelected()$plotXTrellis]]),
+ cols = NULL,
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis=="targetName" & inputSelected()$plotXTrellis!="outcomeName" &
+ inputSelected()$plotYTrellis=="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(targetIdShort),
+ cols = NULL,
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+ else if (inputSelected()$plotXTrellis!="None" & inputSelected()$plotXTrellis!="targetName" & inputSelected()$plotXTrellis=="outcomeName" &
+ inputSelected()$plotYTrellis=="None" & inputSelected()$plotYTrellis!="targetName" & inputSelected()$plotYTrellis!="outcomeName") {
+ base_plot <- base_plot + ggplot2::facet_grid(
+ rows = vars(outcomeIdShort),
+ cols = NULL,
+ scales = if (inputSelected()$irYscaleFixed) "fixed" else "free_y"
+ ) +
+ ggplot2::theme(strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(size = NULL, color = NULL, face="bold")
+ ) +
+ ggh4x::force_panelsizes(rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in"))
+ }
+
+
+ # Rest of your ggplot code remains the same
+ base_plot <- base_plot + ggplot2::labs(
+ title = paste("Incidence Rate for TAR:", tar_value),
+ x = names(options$irPlotCategoricalChoices[options$irPlotCategoricalChoices %in% inputSelected()$plotXAxis]),
+ y = names(options$irPlotNumericChoices[options$irPlotNumericChoices %in% inputSelected()$plotYAxis]),
+ color = names(options$irPlotCategoricalChoices[options$irPlotCategoricalChoices %in% inputSelected()$plotColor]),
+ size = names(options$irPlotNumericChoices[options$irPlotNumericChoices %in% inputSelected()$plotSize]),
+ shape = names(options$irPlotCategoricalChoices[options$irPlotCategoricalChoices %in% inputSelected()$plotShape]
+ )
+ ) +
+ ggplot2::guides(alpha = "none") + # Remove the alpha legend
+ ggplot2::theme_bw() +
+ ggplot2::theme(
+ title = ggplot2::element_text(hjust = 0.5),
+ plot.title = ggplot2::element_text(margin = ggplot2::margin(b = 10)),
+ axis.title.x = ggplot2::element_text(margin = ggplot2::margin(t = 10)),
+ axis.title.y = ggplot2::element_text(margin = ggplot2::margin(r = 10)),
+ legend.box = "horizontal",
+ panel.spacing = ggplot2::unit(1, "lines"),
+ strip.background = ggplot2::element_blank(),
+ strip.text = ggplot2::element_text(face="bold")
+ ) +
+ ggh4x::force_panelsizes(
+ rows = ggplot2::unit(4, "in"), cols = ggplot2::unit(3, "in")
+ )
+
+ #
+ # # Create a custom color scale
+ # color_scale <- RColorBrewer::colorRampPalette(brewer.pal(9, "YlOrRd"))(100)
+ #
+ # # Create a faceted heatmap by outcome and data source
+ # p <- ggplot2::ggplot(data = plotData, aes(x = targetIdShort, y = ageGroupName,
+ # text = paste("Outcome ID:", outcomeIdShort, "
Outcome:", outcomeName,
+ # "
Target ID:", targetIdShort, "
Target:", targetName,
+ # "
TAR:", tar, "
Age:", ageGroupName, "
Sex:", genderName,
+ # "
TAR:",
+ # "
Incidence Rate:", incidenceRateP100py))) +
+ # ggplot2::geom_tile(aes(fill = incidenceRateP100py), color = "white") +
+ # ggplot2::scale_fill_gradient(colors = color_scale, name = "Incidence Rate") +
+ # ggplot2::labs(title = "Incidence Rate by Strata Variables",
+ # x = "Target Population Cohort",
+ # y = "Age Category") +
+ # ggplot2::theme_minimal() +
+ # ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 45, hjust = 1),
+ # plot.title = element_text(hjust = 0.5)) +
+ # ggplot2::facet_grid(outcome ~ data_source, scales = "free_x", space = "free_x")
+ #
+ # # Convert the ggplot plot to a Plotly plot
+ # p <- plotly::ggplotly(p)
+ #
+ #
+
+ }
+
+
+ else {
+
+ shiny::validate("Cannout use the same trellis for row and column, please make another selection.")
+
+ }
+
+ return(base_plot)
+ }
+ )
- # customColDefs <- createCustomColDefList(
- # rawColNames = names(incidenceColList),
- # niceColNames = c("Database",
- # "Ref ID",
- # "Database ID",
- # "Source ID",
- # "Target ID",
- # "Target Name",
- # "Subgroup ID",
- # "Outcome ID",
- # "Outcome Def ID",
- # "Outcome Name",
- # "Clean Window",
- # "Age ID",
- # "Age Group",
- # "Gender ID",
- # "Gender",
- # "Year",
- # "Persons At Risk PE",
- # "Persons At Risk",
- # "Person Days PE",
- # "Person Days",
- # "Person Outcomes PE",
- # "Person Outcomes",
- # "Total Outcomes PE",
- # "Total Outcomes",
- # "Inc. Proportion Per 100P",
- # "Inc. Rate Per 100PY",
- # "Time At Risk"),
- # tooltipText = c("The name of the database",
- # "The reference ID",
- # "The database ID",
- # "The source ID",
- # "The cohort definition ID of the target",
- # "The name of the target cohort",
- # "The name of the subgroup",
- # "The cohort definition ID of the outcome",
- # "The cohort definition ID of the outcome (duplicated)",
- # "The name of the outcome cohort",
- # "The clean window (in days)",
- # "The age ID",
- # "The age group category (in years)",
- # "The gender ID",
- # "The gender category",
- # "The start year of the analysis period",
- # "The distinct persons at risk before removing excluded time (pre-exclude) from TAR",
- # "The distinct persons at risk after removing excluded time from TAR",
- # "Total TAR (in days) before excluded time was removed (pre-exclude)",
- # "Total TAR (in days) after excluded time was removed",
- # "The distinct persons with the outcome before removing excluded time (pre-exclude) from TAR",
- # "The distinct persons with the outcome after removing excluded time from TAR",
- # "Total outcomes before removing excluded time (pre-exclude) from TAR",
- # "Total outcomes after removing excluded time from TAR",
- # "The incidence proportion (per 100 people), calculated by personOutcomes/personsAtRisk*100",
- # "The incidence rate (per 100 person years), calculated by outcomes/personDays/365.25*100",
- # "The TAR window (in days)"
- # ),
- # customColDefOptions = list(
- # list(filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(show = F),
- # list(show = F),
- # list(show = F),
- # list(filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(show = F),
- # list(filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(show = F),
- # list(defaultSortOrder = "desc",
- # filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }
- # ),
- # list(show = F),
- # list(defaultSortOrder = "asc",
- # filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(defaultSortOrder = "desc",
- # filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # }),
- # list(NULL),
- # list(NULL),
- # list(NULL),
- # list(NULL),
- # list(NULL),
- # list(NULL),
- # list(NULL),
- # list(NULL),
- # list(NULL),
- # list(defaultSortOrder = "desc",
- # filterMethod = htmlwidgets::JS('filterMinValue'),
- # filterInput = htmlwidgets::JS('rangeFilter')),
- # list(filterInput = function(values, name) {
- # tags$select(
- # # Set to undefined to clear the filter
- # onchange = sprintf("Reactable.setFilter('incidence-select', '%s', event.target.value || undefined)", name),
- # # "All" has an empty value to clear the filter, and is the default option
- # tags$option(value = "", "All"),
- # lapply(unique(values), tags$option),
- # "aria-label" = sprintf("Filter %s", name),
- # style = "width: 100%; height: 28px;"
- # )
- # })
- # )
- # )
- #
- # # use the below as a guide to save named colDef list as JSON then read it back!
- # ParallelLogger::saveSettingsToJson(customColDefs, "./inst/components-columnInformation/characterization-incidence-colDefs.json")
- # loadTest <- ParallelLogger::loadSettingsFromJson("./inst/components-columnInformation/characterization-incidence-colDefs.json")
+ #render the event reactive incidence plot without legend
+ renderIrPlotNoLegend <- shiny::reactive(
+ {
+ if (is.null(inputSelected()$targetIds) |
+ is.null(inputSelected()$outcomeIds)) {
+ return(data.frame())
+ }
+
+ plotData <- filteredData() %>%
+ dplyr::filter(tar %in% inputSelected()$incidenceRateTarFilter)
+
+ # Get the number of facets in both rows and columns
+ num_rows <- length(unique(plotData[[inputSelected()$plotXTrellis]]))
+ num_cols <- length(unique(plotData[[inputSelected()$plotYTrellis]]))
+
+ max_length <- max(nchar(unique(inputSelected()$plotXAxis)))
+
+ base_plot <- renderIrPlot()
+
+ p <- base_plot +
+ ggplot2::guides(shape = FALSE, color = FALSE, size = FALSE)
+
+ # Convert the ggplot to a plotly object
+ p <- plotly::ggplotly(p, tooltip = "text")
+
+ # Center the main plot title
+ p <- p %>% plotly::layout(title = list(x = 0.5, xanchor = "center"),
+ margin = list(t = 100),
+ xaxis = list(tickangle = 45,
+ title =list(standoff = 40)
+ ),
+ yaxis = list(title =list(standoff = 40)
+ )
+ )
+
+ return(p)
+
+ }
+ )
+ #render the event reactive incidence plot legend only
+ renderIrPlotLegend <- shiny::reactive(
+ {
+ base_plot <- renderIrPlot()
+
+ p <- as_ggplot(cowplot::get_legend(base_plot))
+
+ return(p)
+ }
+ )
- incidenceColList <- ParallelLogger::loadSettingsFromJson(system.file("components-columnInformation",
- "characterization-incidence-colDefs.json",
- package = "OhdsiShinyModules")
- )
+ output$incidencePlot <-
+ plotly::renderPlotly({
+ renderIrPlotNoLegend()
+ })
- resultTableServer(id = "incidenceRateTable",
- df = allData,
- selectedCols = c("cdmSourceAbbreviation", "targetName", "outcomeName",
- "ageGroupName", "genderName", "startYear", "tar", "outcomes",
- "incidenceProportionP100p", "incidenceRateP100py"),
- sortedCols = c("ageGroupName", "genderName", "startYear", "incidenceRateP100py"),
- elementId = "incidence-select",
- colDefsInput = incidenceColList,
- downloadedFileName = "incidenceRateTable-")
+ output$incidencePlotLegend <-
+ shiny::renderPlot({
+ renderIrPlotLegend()
+ })
+
return(invisible(NULL))
})
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#allDataDownload(allData)
-
-# do the plots reactively
-# output$incTable <- reactable::renderReactable(
-# {
-# reactable::reactable(
-# data = allData %>%
-# dplyr::relocate("tar", .after = "cdmSourceAbbreviation") %>%
-# dplyr::relocate("personsAtRisk", .after = "tar") %>%
-# dplyr::relocate("personDays", .after = "personsAtRisk") %>%
-# dplyr::relocate("personOutcomes", .after = "personDays") %>%
-# dplyr::relocate("incidenceProportionP100p", .after = "personOutcomes") %>%
-# dplyr::relocate("incidenceRateP100py", .after = "incidenceProportionP100p")
-# ,
-# filterable = TRUE,
-# showPageSizeOptions = TRUE,
-# pageSizeOptions = c(10, 50, 100,1000),
-# defaultPageSize = 50,
-# striped = TRUE,
-# highlight = TRUE,
-# elementId = "desc-incidence-select",
-#
-# columns = list(
-# cdmSourceAbbreviation = reactable::colDef(
-# name = 'Database',
-# sticky = "left",
-# filterInput = function(values, name) {
-# shiny::tags$select(
-# # Set to undefined to clear the filter
-# onchange = sprintf("Reactable.setFilter('desc-incidence-select', '%s', event.target.value || undefined)", name),
-# # "All" has an empty value to clear the filter, and is the default option
-# shiny::tags$option(value = "", "All"),
-# lapply(unique(values), shiny::tags$option),
-# "aria-label" = sprintf("Filter %s", name),
-# style = "width: 100%; height: 28px;"
-# )
-# }
-# ),
-# tar = reactable::colDef(
-# filterInput = function(values, name) {
-# shiny::tags$select(
-# # Set to undefined to clear the filter
-# onchange = sprintf("Reactable.setFilter('desc-incidence-select', '%s', event.target.value || undefined)", name),
-# # "All" has an empty value to clear the filter, and is the default option
-# shiny::tags$option(value = "", "All"),
-# lapply(unique(values), shiny::tags$option),
-# "aria-label" = sprintf("Filter %s", name),
-# style = "width: 100%; height: 28px;"
-# )
-# }
-# ),
-# refId = reactable::colDef(show = F),
-# databaseId = reactable::colDef(show = F),
-# sourceName = reactable::colDef(show = F),
-# targetCohortDefinitionId = reactable::colDef(show = F),
-# targetName = reactable::colDef(show = F),
-# outcomeId = reactable::colDef(show = F),
-# outcomeCohortDefinitionId = reactable::colDef(show = F),
-# outcomeName = reactable::colDef(show = F),
-# outcomeId = reactable::colDef(show = F),
-# ageId = reactable::colDef(show = F),
-# genderId = reactable::colDef(show = F),
-# subgroupId = reactable::colDef(show = F),
-# incidenceProportionP100p = reactable::colDef(
-# format = reactable::colFormat(digits = 4)
-# ),
-# incidenceRateP100py = reactable::colDef(
-# format = reactable::colFormat(digits = 4)
-# )
-# )
-#
-#
-#
-#
-# )
-# }
-# )
-#
-# }
-# )
-#
-# # download
-# output$downloadInc <- shiny::downloadHandler(
-# filename = function() {
-# paste('incidence-data-', Sys.Date(), '.csv', sep='')
-# },
-# content = function(con) {
-# utils::write.csv(allDataDownload(), con)
-# }
-# )
-#
-#
-# return(invisible(NULL))
-#
-# }
-# )
-# }
-
+
+
getIncidenceData <- function(
targetIds,
outcomeIds,
@@ -591,85 +1018,199 @@ getIncidenceData <- function(
resultDatabaseSettings
){
- #shiny::withProgress(message = 'Getting incidence data', value = 0, {
-
- sql <- 'select d.cdm_source_abbreviation, i.*
+ if(!is.null(targetIds) & !is.null(outcomeIds)){
+
+ #shiny::withProgress(message = 'Getting incidence data', value = 0, {
+
+ sql <- 'select d.cdm_source_abbreviation, i.*
from @result_schema.@incidence_table_prefixINCIDENCE_SUMMARY i
inner join @result_schema.@database_table_name d
on d.database_id = i.database_id
where target_cohort_definition_id in (@target_ids)
and outcome_cohort_definition_id in (@outcome_ids)
;'
+
+ #shiny::incProgress(1/2, detail = paste("Created SQL - Extracting..."))
+
+ resultTable <- connectionHandler$queryDb(
+ sql = sql,
+ result_schema = resultDatabaseSettings$schema,
+ incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix,
+ target_ids = paste(as.double(targetIds), collapse = ','),
+ outcome_ids = paste(as.double(outcomeIds), collapse = ','),
+ database_table_name = resultDatabaseSettings$databaseTable
+ )
+
+ #shiny::incProgress(2/2, detail = paste("Done..."))
+
+ #})
+
+ # format the tar
+ resultTable$tar <- paste0('(',resultTable$tarStartWith, " + ", resultTable$tarStartOffset, ') - (', resultTable$tarEndWith, " + ", resultTable$tarEndOffset, ')')
+ resultTable <- resultTable %>%
+ dplyr::select(-c("tarStartWith","tarStartOffset","tarEndWith","tarEndOffset", "tarId", "subgroupName"))
+
+ resultTable[is.na(resultTable)] <- 'All'
+ resultTable <- unique(resultTable)
+
+ return(resultTable)
+ } else{
+ return(NULL)
+ }
+}
+
+
+getIncidenceOptions <- function(
+ connectionHandler,
+ resultDatabaseSettings
+){
+
+ # shiny::withProgress(message = 'Getting incidence inputs', value = 0, {
+
+ sql <- 'select distinct target_cohort_definition_id, target_name
+ from @result_schema.@incidence_table_prefixINCIDENCE_SUMMARY;'
- #shiny::incProgress(1/2, detail = paste("Created SQL - Extracting..."))
+ #shiny::incProgress(1/3, detail = paste("Created SQL - Extracting targets"))
- resultTable <- connectionHandler$queryDb(
+ targets <- connectionHandler$queryDb(
sql = sql,
result_schema = resultDatabaseSettings$schema,
- incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix,
- target_ids = paste(as.double(targetIds), collapse = ','),
- outcome_ids = paste(as.double(outcomeIds), collapse = ','),
- database_table_name = resultDatabaseSettings$databaseTable
+ incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix
)
+ targetIds <- targets$targetCohortDefinitionId
+ names(targetIds) <- targets$targetName
- #shiny::incProgress(2/2, detail = paste("Done..."))
+ sql <- 'select distinct outcome_cohort_definition_id, outcome_name
+ from @result_schema.@incidence_table_prefixINCIDENCE_SUMMARY;'
- #})
+ #shiny::incProgress(2/3, detail = paste("Created SQL - Extracting outcomes"))
- # format the tar
- resultTable$tar <- paste0('(',resultTable$tarStartWith, " + ", resultTable$tarStartOffset, ') - (', resultTable$tarEndWith, " + ", resultTable$tarEndOffset, ')')
- resultTable <- resultTable %>%
- dplyr::select(-c("tarStartWith","tarStartOffset","tarEndWith","tarEndOffset", "tarId", "subgroupName"))
+ outcomes <- connectionHandler$queryDb(
+ sql = sql,
+ result_schema = resultDatabaseSettings$schema,
+ incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix
+ )
- resultTable[is.na(resultTable)] <- 'All'
- resultTable <- unique(resultTable)
+ outcomeIds <- outcomes$outcomeCohortDefinitionId
+ names(outcomeIds) <- outcomes$outcomeName
- return(resultTable)
-}
-
-
-getTargetOutcomes <- function(
- connectionHandler,
- resultDatabaseSettings
-){
+ sql <- 'select distinct tar_id, tar_start_with, tar_start_offset, tar_end_with, tar_end_offset
+ from @result_schema.@incidence_table_prefixINCIDENCE_SUMMARY;'
- shiny::withProgress(message = 'Getting incidence inputs', value = 0, {
-
- sql <- 'select distinct target_cohort_definition_id, target_name
+ #shiny::incProgress(1/3, detail = paste("Created SQL - Extracting targets"))
+
+ tars <- connectionHandler$queryDb(
+ sql = sql,
+ result_schema = resultDatabaseSettings$schema,
+ incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix
+ )
+ tar <- tars$tarId
+ names(tar) <- paste0('(',tars$tarStartWith, " + ", tars$tarStartOffset, ') - (', tars$tarEndWith, " + ", tars$tarEndOffset, ')')
+
+ sql <- 'select distinct age_group_name
from @result_schema.@incidence_table_prefixINCIDENCE_SUMMARY;'
-
- shiny::incProgress(1/3, detail = paste("Created SQL - Extracting targets"))
-
- targets <- connectionHandler$queryDb(
- sql = sql,
- result_schema = resultDatabaseSettings$schema,
- incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix
- )
- targetIds <- targets$targetCohortDefinitionId
- names(targetIds) <- targets$targetName
-
- sql <- 'select distinct outcome_cohort_definition_id, outcome_name
+
+ result <- connectionHandler$queryDb(
+ sql = sql,
+ result_schema = resultDatabaseSettings$schema,
+ incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix
+ )
+
+ ageGroupName <- result$ageGroupName
+ ageGroupName[is.na(ageGroupName)] <- 'All'
+ ageGroupName <- sort(ageGroupName)
+
+ sql <- 'select distinct gender_name
+ from @result_schema.@incidence_table_prefixINCIDENCE_SUMMARY;'
+
+ result <- connectionHandler$queryDb(
+ sql = sql,
+ result_schema = resultDatabaseSettings$schema,
+ incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix
+ )
+
+ genderName <- result$genderName
+ genderName[is.na(genderName)] <- 'All'
+ genderName <- sort(genderName)
+
+ sql <- 'select distinct start_year
from @result_schema.@incidence_table_prefixINCIDENCE_SUMMARY;'
-
- shiny::incProgress(2/3, detail = paste("Created SQL - Extracting outcomes"))
-
- outcomes <- connectionHandler$queryDb(
- sql = sql,
- result_schema = resultDatabaseSettings$schema,
- incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix
- )
-
- outcomeIds <- outcomes$outcomeCohortDefinitionId
- names(outcomeIds) <- outcomes$outcomeName
-
- shiny::incProgress(3/3, detail = paste("Done"))
- })
+
+ result <- connectionHandler$queryDb(
+ sql = sql,
+ result_schema = resultDatabaseSettings$schema,
+ incidence_table_prefix = resultDatabaseSettings$incidenceTablePrefix
+ )
+
+ startYear <- result$startYear
+ startYear[is.na(startYear)] <- 'All'
+ startYear <- sort(startYear)
+
+ # shiny::incProgress(3/3, detail = paste("Done"))
+ # })
+
+ irPlotCategoricalChoices <- list(
+ "cdmSourceAbbreviation",
+ "ageGroupName",
+ "genderName",
+ "startYear",
+ "targetName",
+ "outcomeName",
+ "tar",
+ "cleanWindow",
+ "None"
+ )
+ names(irPlotCategoricalChoices) <- c(
+ "Data Source",
+ "Age Group",
+ "Sex",
+ "Calendar Year",
+ "Target Cohort",
+ "Outcome Cohort",
+ "TAR",
+ "Clean Window",
+ "None"
+ )
+
+ irPlotNumericChoices <- list(
+ "incidenceRateP100py",
+ "incidenceProportionP100p",
+ "outcomes",
+ "outcomesPe",
+ "personOutcomes",
+ "personOutcomesPe",
+ "personsAtRisk",
+ "personsAtRiskPe",
+ "personDays",
+ "personDaysPe",
+ "None"
+ )
+ names(irPlotNumericChoices) <- c(
+ "Incidence Rate (per 100PY)",
+ "Incidence Proportion (per 100P)",
+ "Outcomes",
+ "Outcomes PE",
+ "Person Outcomes",
+ "Person Outcomes PE",
+ "Persons At Risk",
+ "Persons At Risk PE",
+ "Person Days",
+ "Person Days PE",
+ "None"
+ )
return(
list(
targetIds = targetIds,
- outcomeIds = outcomeIds
+ outcomeIds = outcomeIds,
+ tar = tar,
+ irPlotNumericChoices = irPlotNumericChoices,
+ irPlotCategoricalChoices = irPlotCategoricalChoices,
+ ageGroupName = ageGroupName,
+ genderName = genderName,
+ startYear = startYear
)
)
}
+
diff --git a/R/components-inputselection.R b/R/components-inputselection.R
index 85265418..40a438a9 100644
--- a/R/components-inputselection.R
+++ b/R/components-inputselection.R
@@ -34,22 +34,27 @@ createInputSetting <- function(
rowNumber,
columnWidth = 4,
varName = '',
+ inputReturn = T,
uiFunction = 'shinyWidgets::pickerInput',
uiInputs = list(
label = 'Input: ',
choices = list(),
multiple = F,
options = shinyWidgets::pickerOptions()
- )
-
+ ),
+ updateFunction = NULL,
+ collapse = F
){
result <- list(
rowNumber = rowNumber,
columnWidth = columnWidth,
varName = varName,
+ inputReturn = inputReturn,
uiFunction = uiFunction,
- uiInputs = uiInputs
+ uiInputs = uiInputs,
+ updateFunction = updateFunction,
+ collapse = collapse
)
class(result) <- 'inputSetting'
@@ -78,7 +83,11 @@ inputSelectionServer <- function(
lapply(which(rowNumbers == i), function(x){
inputs <- inputSettingList[[x]]$uiInputs
- inputs$inputId <- session$ns(paste0('input_',x))
+ if(inputSettingList[[x]]$inputReturn){
+ # if using a function that has no return (e.g., div) set
+ # inputReturn = F
+ inputs$inputId <- session$ns(paste0('input_',x))
+ }
shiny::column(
width = inputSettingList[[x]]$columnWidth,
@@ -93,6 +102,12 @@ inputSelectionServer <- function(
label = 'Generate Report'
)
+ # add reset here
+ rows[[length(rows)+1]] <- shiny::actionButton(
+ inputId = session$ns('reset'),
+ label = 'Reset'
+ )
+
output$inputs <- shiny::renderUI({
shiny::fluidPage(rows)
})
@@ -130,9 +145,25 @@ inputSelectionServer <- function(
if(is.null(names(inputSettingList[[x]]$uiInputs$choices))){
names(inputSettingList[[x]]$uiInputs$choices) <- inputSettingList[[x]]$uiInputs$choices
}
- paste(names(inputSettingList[[x]]$uiInputs$choices)[inputSettingList[[x]]$uiInputs$choices %in% input[[paste0('input_',x)]]], collapse = ',')
+
+ # add selections on new row unless collapse is F
+ if(!inputSettingList[[x]]$collapse){
+ shiny::HTML(
+ paste("
", names(inputSettingList[[x]]$uiInputs$choices)[inputSettingList[[x]]$uiInputs$choices %in% input[[paste0('input_',x)]]], '
') + ) + } else{ + paste(names(inputSettingList[[x]]$uiInputs$choices)[inputSettingList[[x]]$uiInputs$choices %in% input[[paste0('input_',x)]]], collapse = ', ') + } } else{ - paste(input[[paste0('input_',x)]], collapse = ',') + + # add selections on new row unless collapse is F + if(!inputSettingList[[x]]$collapse){ + shiny::HTML( + paste("", input[[paste0('input_',x)]], '
') + ) + } else{ + paste(input[[paste0('input_',x)]], collapse = ', ') + } } ) } @@ -142,6 +173,28 @@ inputSelectionServer <- function( selectedInputText(shiny::div(otext)) }) + + # do the reset stuff + shiny::observeEvent( + eventExpr = input$reset, + { + # code to reset to default + + for(i in 1:length(inputSettingList)){ + if(!is.null(inputSettingList[[i]]$updateFunction)){ + + # need to test for non-picker inputs + do.call(eval(parse(text = inputSettingList[[i]]$updateFunction)), + list( + session = session, + inputId = paste0('input_',i), + selected = inputSettingList[[i]]$uiInputs$selected + )) + + } + } + }) + return(selectedInput) } diff --git a/R/patient-level-prediction-designSummary.R b/R/patient-level-prediction-designSummary.R index 772c9fe8..bde3ddc8 100644 --- a/R/patient-level-prediction-designSummary.R +++ b/R/patient-level-prediction-designSummary.R @@ -82,6 +82,7 @@ patientLevelPredictionDesignSummaryServer <- function( columnWidth = 6, varName = 'targetIds', uiFunction = 'shinyWidgets::pickerInput', + updateFunction = 'shinyWidgets::updatePickerInput', uiInputs = list( label = 'Target: ', choices = targetIds, @@ -102,6 +103,7 @@ patientLevelPredictionDesignSummaryServer <- function( columnWidth = 6, varName = 'outcomeIds', uiFunction = 'shinyWidgets::pickerInput', + updateFunction = 'shinyWidgets::updatePickerInput', uiInputs = list( label = 'Outcome: ', choices = outcomeIds,