Nothing
shinyServer(function(input, output, session) {
subject <- shiny::reactiveValues(index = 1)
dataFromRds <- shiny::reactive({
readData(
databaseId = input$selectedDatabaseId,
cohortId = input$selectedCohortId
)
})
subjectIds <- shiny::reactive({
dataFromRds()$cohort$personId %>% sort()
})
selectedSubjectId <- shiny::reactive({
if (subject$index) {
subjectIds()[subject$index]
}
})
cohortAndObservationPeriod <- shiny::reactive({
cohortFiltered <- dataFromRds()$cohort %>%
dplyr::filter(personId == subjectIds()[subject$index]) %>%
dplyr::mutate(
domain = "Cohort",
cdmTable = "Cohort",
conceptName = "Cohort entry",
typeConceptName = "Cohort entry"
) %>%
dplyr::select(startDate,
endDate,
domain,
conceptName,
typeConceptName,
cdmTable)
observationPeriodFiltered <- dataFromRds()$observationPeriod %>%
dplyr::filter(personId == subjectIds()[subject$index]) %>%
dplyr::select(startDate,
endDate,
typeConceptId) %>%
dplyr::mutate(cdmTable = "Observation Period",
domain = "Observation Period",
conceptName = "Observation Period") %>%
dplyr::left_join(
dataFromRds()$conceptId %>%
dplyr::rename("typeConceptName" = "conceptName") %>%
dplyr::select(-domainId),
by = c("typeConceptId" = "conceptId")
)
data <- dplyr::bind_rows(cohortFiltered,
observationPeriodFiltered) %>%
dplyr::arrange(cdmTable, startDate)
data$firstOccurrenceDate <- min(cohortFiltered$startDate)
return(data)
})
queryResult <- shiny::reactive({
filteredConceptIds <- dataFromRds()$conceptId
if (is.null(input$cdmTables)) {
return(cohortAndObservationPeriod())
} else {
if (input$filterRegex != "") {
tryCatch(
expr = {
filteredConceptIds <- filteredConceptIds %>%
dplyr::filter(stringr::str_detect(
string = tolower(conceptName),
pattern = tolower(input$filterRegex)
))
},
error = function(e) {
showNotification("please check the regular expression for error", "", type = "error")
return()
}
)
}
if (input$deleteRegex != "") {
tryCatch(
expr = {
filteredConceptIds <- filteredConceptIds %>%
dplyr::filter(stringr::str_detect(
string = tolower(conceptName),
pattern = tolower(input$deleteRegex),
negate = TRUE
))
},
error = function(e) {
showNotification("please check the regular expression for error", "", type = "error")
return()
}
)
}
selectedCdmTables <-
gsub(
pattern = " ",
replacement = "_",
x = tolower(input$cdmTables)
)
data <- dplyr::tibble()
for (i in (1:length(selectedCdmTables))) {
domainTableData <-
dataFromRds()[[snakeCaseToCamelCase(selectedCdmTables[[i]])]] %>%
dplyr::filter(personId == subjectIds()[subject$index]) %>%
dplyr::mutate(cdmTable = selectedCdmTables[[i]])
if (selectedCdmTables[[i]] == "feature_cohort_data") {
cohortDefinitionSet <-
dataFromRds()$featureCohortDefinitionSet |>
dplyr::select(cohortId,
cohortName) |>
dplyr::rename(conceptId = cohortId,
conceptName = cohortName)
}
if (!'endDate' %in% colnames(domainTableData)) {
domainTableData <- domainTableData %>%
dplyr::mutate(endDate = startDate)
}
domainTableData <- domainTableData %>%
dplyr::mutate(endDate = dplyr::if_else(
condition = is.na(endDate),
true = startDate,
false = endDate
))
data <- dplyr::bind_rows(data,
domainTableData)
}
if (input$showSourceCode) {
data <- data %>%
dplyr::filter(sourceConceptId >= 0) %>%
dplyr::mutate(conceptId = sourceConceptId) %>%
dplyr::select(-sourceConceptId) %>%
dplyr::group_by(personId,
startDate,
endDate,
conceptId,
typeConceptId,
cdmTable) %>%
dplyr::summarise(records = sum(records),
.groups = "keep") %>%
dplyr::ungroup()
} else {
data <- data %>%
dplyr::filter(conceptId >= 0)
if ("sourceConceptId" %in% colnames(data)) {
data <- data %>%
dplyr::select(-sourceConceptId)
}
data <- data %>%
dplyr::group_by(personId,
startDate,
endDate,
conceptId,
typeConceptId,
cdmTable) %>%
dplyr::summarise(records = sum(records),
.groups = "keep") %>%
dplyr::ungroup()
}
dataFiltered <- data |>
dplyr::filter(!cdmTable == "feature_cohort_data") %>%
dplyr::inner_join(filteredConceptIds,
by = "conceptId")
if (exists("cohortDefinitionSet")) {
featureCohortData <- data |>
dplyr::filter(cdmTable == "feature_cohort_data") |>
dplyr::inner_join(cohortDefinitionSet,
by = "conceptId") |>
dplyr::mutate(vocabularyId = "Cohort",
conceptCode = as.character(conceptId),
typeConceptId = 0,
records = 1)
dataFiltered <- dplyr::bind_rows(dataFiltered,
featureCohortData)
}
data <- dataFiltered
if (isFALSE(input$showSourceCode)) {
data <- data %>%
dplyr::select(-conceptCode, -vocabularyId)
}
data <- data %>%
dplyr::left_join(
dataFromRds()$conceptId %>%
dplyr::rename("typeConceptName" = "conceptName") %>%
dplyr::select(-domainId, -vocabularyId, -conceptCode),
by = c("typeConceptId" = "conceptId")
) %>%
dplyr::select(-typeConceptId)
data <- data %>%
dplyr::rename(domain = domainId) %>%
dplyr::select(-personId)
firstOccurrenceDateValue <-
cohortAndObservationPeriod()$firstOccurrenceDate %>% unique()
cohortData <-
cohortAndObservationPeriod() %>% dplyr::select(intersect(colnames(data),
colnames(cohortAndObservationPeriod())))
data <- dplyr::bind_rows(cohortData,
data) %>%
dplyr::mutate(daysToFirst = firstOccurrenceDateValue - startDate)
if (all(!is.null(input$daysFromCohortStart),
input$daysFromCohortStart != '')) {
data <- data %>%
dplyr::filter(as.integer(daysToFirst) * -1 <= input$daysFromCohortStart)
}
if (all(!is.null(input$daysToCohortStart),
input$daysFromCohortStart != '')) {
data <- data %>%
dplyr::filter(as.integer(daysToFirst) <= input$daysToCohortStart)
}
if (isTRUE(input$shiftDates)) {
earliestDate <- cohortAndObservationPeriod() %>%
dplyr::select(startDate) %>%
dplyr::summarise(startDate = as.Date(min(startDate))) %>%
dplyr::pull(startDate)
data <- data %>%
dplyr::mutate(startDate = addDays(x = as.Date(originDate),
n = as.integer(
difftime(
time1 = startDate,
time2 = earliestDate,
units = "days"
)
))) %>%
dplyr::mutate(endDate = addDays(x = as.Date(originDate),
n = as.integer(
difftime(
time1 = endDate,
time2 = earliestDate,
units = "days"
)
)))
}
return(data)
}
})
filteredEvents <- shiny::reactive({
events <- queryResult()
if (nrow(events) != 0) {
events <- events[order(events$conceptId), ]
getY <- function(subset) {
uniqueConceptIds <- unique(subset$conceptId)
subset$y <- match(subset$conceptId, uniqueConceptIds)
return(subset)
}
events <- lapply(split(events, events$cdmTable), getY)
events <- do.call("rbind", events)
}
return(events)
})
colorScale <- shiny::reactive({
selectedCdmTables <- input$cdmTables
if (length(selectedCdmTables) > 0) {
selectedCdmTables <-
gsub(
pattern = " ",
replacement = "_",
x = tolower(selectedCdmTables)
)
}
tables <- c("Cohort", "Observation Period", selectedCdmTables)
if (length(tables) == 2) {
colors <- c("Red", "Orange")
} else {
temp <-
RColorBrewer::brewer.pal(n = max(3, length(tables) - 2), name = "Set2")
colors <- c("Red", "Orange", temp[1:(length(tables) - 2)])
}
names(colors) <- tables
return(colors)
})
shiny::observeEvent(input$nextButton, {
if (subject$index < length(subjectIds())) {
subject$index <- subject$index + 1
}
})
shiny::observeEvent(input$previousButton, {
if (subject$index > 1) {
subject$index <- subject$index - 1
}
})
output$cohortName <- shiny::renderText({
cohortName <- "Unknown"
if (!is.null(dataFromRds()$cohortName)) {
cohortName <- dataFromRds()$cohortName
}
return(cohortName)
})
output$subjectId <- shiny::renderText({
return(subjectIds()[subject$index])
})
output$age <- shiny::renderText({
selectedSubjectId <- subjectIds()[subject$index][1]
age <- dataFromRds()$person %>%
dplyr::filter(personId == selectedSubjectId) %>%
dplyr::pull(age)
return(age)
})
output$gender <- shiny::renderText({
selectedSubjectId <- subjectIds()[subject$index][1]
gender <- dataFromRds()$subjects %>%
dplyr::filter(personId == selectedSubjectId) %>%
dplyr::pull(gender)
return(gender)
})
output$eventTable <- reactable::renderReactable(expr = {
data <- filteredEvents() %>%
dplyr::arrange(abs(daysToFirst)) %>%
dplyr::select(-conceptId, -y) %>%
dplyr::relocate(daysToFirst,
conceptName,
typeConceptName,
startDate,
endDate,
domain,
cdmTable)
colnames(data) <-
camelCaseToTitleCase(colnames(data))
dataTable <- reactable::reactable(
data = data,
sortable = TRUE,
resizable = TRUE,
filterable = TRUE,
searchable = TRUE,
pagination = TRUE,
showPagination = TRUE,
showPageInfo = TRUE,
highlight = TRUE,
striped = TRUE,
compact = TRUE,
showSortIcon = TRUE,
showSortable = TRUE,
fullWidth = TRUE,
borderless = TRUE,
onClick = "select",
wrap = TRUE,
showPageSizeOptions = TRUE,
pageSizeOptions = c(10, 20, 50, 100, 1000),
defaultPageSize = 1000
)
return(dataTable)
})
output$plotSmall <- plotly::renderPlotly(plot())
output$plotBig <- plotly::renderPlotly(plot())
plot <- shiny::reactive({
events <- filteredEvents()
if (nrow(events) == 0) {
return(NULL)
} else {
colors <- colorScale()
cdmTables <- events %>%
dplyr::group_by(cdmTable) %>%
dplyr::summarise(y = max(y), .groups = "keep") %>%
dplyr::ungroup()
cdmTables <- cdmTables[order(cdmTables$cdmTable), ]
cdmTables$offset <- cumsum(cdmTables$y) - cdmTables$y
events <- merge(events, cdmTables[, c("cdmTable", "offset")])
events$y <- events$y + events$offset
yRange <- c(min(events$y) - 1, max(events$y) + 1)
events$text <-
sprintf(
"%s - %s<br>%s<br>%s<br>%s<br>%s<br>%s",
events$startDate,
events$endDate,
events$conceptName,
events$conceptId,
events$domain,
events$cdmTable,
events$typeConceptName
)
eventsPerY <- events %>%
dplyr::group_by(y) %>%
dplyr::summarise(cdmTable = length(y), .groups = "keep") %>%
dplyr::ungroup()
yGrid <- eventsPerY$y[eventsPerY$cdmTable > 1]
yAxis <- list(
title = "",
tickmode = "array",
tickvals = yGrid,
zeroline = FALSE,
showline = FALSE,
showticklabels = FALSE,
showgrid = TRUE,
range = yRange,
fixedrange = TRUE
)
xAxis <- list(
title = "",
zeroline = FALSE,
showline = FALSE,
showticklabels = TRUE,
showgrid = TRUE
)
plot <- plotly::plot_ly() %>%
plotly::add_trace(
data = events,
x = ~ startDate,
y = ~ y,
color = ~ cdmTable,
colors = colors,
type = 'scatter',
mode = 'markers',
text = ~ text,
hovertemplate = "%{text}"
) %>%
plotly::add_segments(
data = events,
x = ~ startDate,
y = ~ y,
xend = ~ endDate,
yend = ~ y,
color = ~ cdmTable,
showlegend = FALSE,
hoverinfo = "skip"
)
shapes <- list()
cohortData <- events %>%
dplyr::filter(cdmTable == "Cohort") %>%
dplyr::select(startDate,
endDate) %>%
dplyr::distinct() %>%
dplyr::arrange(startDate)
first <- TRUE
for (i in (1:nrow(cohortData))) {
data <- data.frame(
date = rep(cohortData$startDate[i], 2),
y = rep(yRange, 2),
text = sprintf("%s - %s",
cohortData$startDate[i],
cohortData$endDate[i])
)
plot <- plot %>% plotly::add_lines(
x = ~ date,
y = ~ y,
data = data,
mode = "lines",
line = list(color = colors["Cohort"]),
name = "Cohort",
text = ~ text,
hovertemplate = "%{text}",
showlegend = first
)
first <- FALSE
if (!is.na(cohortData$endDate[i])) {
shapes[[length(shapes) + 1]] <- list(
type = "rect",
fillcolor = "red",
line = list(color = colors["Cohort"]),
opacity = 0.3,
x0 = cohortData$startDate[i],
x1 = cohortData$endDate[i],
xref = "startDate",
y0 = yRange[1],
y1 = yRange[2],
yref = "y"
)
}
}
plot <- plot %>% plotly::layout(
yaxis = yAxis,
xaxis = xAxis,
shapes = shapes,
legend = list(orientation = 'h'),
margin = list(
l = 1,
r = 1,
b = 1,
t = 25,
pad = 1
)
)
return(plot)
}
})
shiny::observeEvent(input$filterInfo, {
showModal(
modalDialog(
title = "Concept Name Filter",
easyClose = TRUE,
footer = NULL,
size = "l",
HTML(
"Filter the concept to include in the plot and table by concept name using a regular expression.
For example, the regular expression 'celecox|diclof' finds concepts like 'Celecoxib 200mg Oral Tablet' and 'Diclofenac'.
See <a href='https://en.wikipedia.org/wiki/Regular_expression'>Wikipedia</a> for more information on regular expressions."
)
)
)
})
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.