Nothing
#' doseDesign module ui function
#'
#' @description A shiny Module for the doseDesign-tab in dosedesignR.
#'
#' @param id Internal parameters for {shiny}.
#'
#' @noRd
#'
#' @importFrom shiny NS tagList
doseDesignUI <- function(id) {
dosedesignR_green <- "#5cb85c"
dosedesignR_blue <- "#3a6791"
dosedesignR_red <- "#c94053"
ns <- shiny::NS(id)
shiny::tagList(
shiny::column(4,
shinyBS::bsCollapse(
shinyBS::bsCollapsePanel(title = paste0("Candidate Model ", as.character(id)),
shiny::selectInput(
inputId = ns("model"),
label = NULL,
choices = c(
"Linear", "Emax", "Sigmoidal Emax"
),
selected = rep(
c(
"Linear", "Emax", "Sigmoidal Emax"
), as.numeric(id)
)[as.numeric(id)]
),
shiny::textOutput(ns("model")),
shiny::column(4,
shinyWidgets::materialSwitch(
ns("parambox"),
HTML('<p style="color:white"> Show Parameter </p>'),
value = TRUE,
status = "success"
)
),
shiny::column(4,
shinyWidgets::materialSwitch(
ns("paramesti"),
HTML('<p style="color:white"> Show Estimates </p>'),
value = TRUE,
status = "success"
)
),
shiny::column(4,
shinyWidgets::materialSwitch(
ns("plot_opt"),
HTML(
'<p style="color:white"> Show Optimal Curve </p>'
),
value = TRUE,
status = "success"
)
),
shiny::column(10,
shiny::tableOutput(ns("showEstimates")),
shiny::tags$head(
shiny::tags$style(
"#ShowEstimates td{position:relative;};"
)
)
),
shiny::column(12,
shiny::column(6,
shiny::numericInput(ns("parameter1"),
label = "",
value = rep(0,100)[as.numeric(id)])
),
shiny::column(6,
shiny::numericInput(ns("parameter2"),
label = "",
value = rep(1,100)[as.numeric(id)])
)
),
shiny::column(12,
shiny::column(6,
shiny::numericInput(ns("parameter3"),
label = "",
value = rep(0.5,100)[as.numeric(id)])
),
shiny::column(6,
shiny::numericInput(ns("parameter4"),
label = "",
value = rep(5,100)[as.numeric(id)])
)
),
shiny::column(12,
shiny::actionButton(
ns("go_stand"),
"Standardize",
icon = icon("chart-line"),
style = paste0("color: #fff; background-color: ", dosedesignR_blue, "; border-color: #2e6da4")
),
shiny::actionButton(
ns("undoButton"),
"Undo Standardize!",
icon = icon("undo"),
style = paste0("color: #fff; background-color: ", dosedesignR_blue, "; border-color: #2e6da4")
)
),
shiny::tabsetPanel(type = "tabs",
shiny::tabPanel("Plot",
shiny::column(12, style = "background-color:#383838;",
shiny::plotOutput(ns("modelFunction"), width = "100%")
)
),
shiny::tabPanel("Simulation",
simModule_UI(paste0("s",id))
)
),
shiny::column(12,
style = "background-color:#383838;",
shiny::plotOutput(ns("optDesign"))
),
shiny::column(12, align = "center",
shiny::wellPanel(style = "background: #333333; border: black",
shiny::tableOutput(ns("viewOpt"))
)
),
shiny::column(12,
# call module from file 'doseLevel_Module.R' to enter dose
# groups and dose levels
doseLevelUI(ns("oM1"))
),
shiny::column(12, align = "center",
shiny::wellPanel(style = "background: #333333; border: black",
shiny::tableOutput(ns("viewEff")))
)
), id = paste0("Tab", as.character(id)),
# let only the first 2 tabs be open at the start
open = paste0("Candidate Model ", as.character(id))
)
)
)
}
#' doseDesign module server function
#'
#' @param input,output,session Internal parameters for {shiny}.
#' @param nr panel number
#' @param levels level information (from app)
#' @param regimen regimen information (from app)
#' @param npats number of patients (from app)
#' @param dmin dose minimum (from app)
#' @param dmax dose maximum (from app)
#' @param ymin y-axis minimum (from app)
#' @param ymax y-axis maximum (from app)
#' @param sdsim simulation options (from app)
#' @param clevel level information (from app)
#' @param data data set (from app)
#' @param data2 second data set
#' @param selectnr Which data set (if multiple in .rds file) are selected
#' @param button save.button click
#' @param nrPanel total number of panels
#' @noRd
doseDesign <- function(
input,
output,
session,
nr, # numeric value: panel number
levels,
regimen,
npats,
dmin, # dose minimum
dmax, # dose maximum
ymin, # y axis minimum
ymax, # y axis maximum
sdsim, # simulation options
clevel,# level inforation
data, # df()
data2, # da()
selectnr, # which data sets (if multiple in .rds file) are selected
button, # save.button click
nrPanel # total number of panels
){
#condition that the switchInputs are only shown when a data set is loaded data2()
shiny::observeEvent(c(data2(), input$paramesti), {
if (!is.null(data2())) {
shinyjs::show("paramesti")
if (input$paramesti) {
shinyjs::show("showEstimates")
} else {
shinyjs::hide("showEstimates")
}
shinyjs::show("plot_opt")
} else {
shinyjs::hide("paramesti")
shinyjs::hide("plot_opt")
}
})
# hide the parameters if switchInput parambox is false and
# limit the number of parameter shown for the selected model if parambox is true
shiny::observeEvent(c(input$model,input$parambox), {
if (input$parambox) {
shinyjs::show("parameter1")
shinyjs::show("parameter2")
if (input$model %in% c('Linear', 'Linear in log')) {
shinyjs::hide("parameter3")
shinyjs::hide("parameter4")
} else if (input$model %in% c('Emax')) {
shinyjs::show("parameter3")
shinyjs::hide("parameter4")
} else {
shinyjs::show("parameter3")
shinyjs::show("parameter4")
}
} else {
shinyjs::hide("parameter1")
shinyjs::hide("parameter2")
shinyjs::hide("parameter3")
shinyjs::hide("parameter4")
}
})
# call module from file 'doseLevel_Module.R' to enter dose
# groups and dose levels
oM <- shiny::callModule(doseLevel, "oM1")
optValue <- shiny::reactiveValues()
UserValue <- shiny::reactiveValues()
# create reactive value start$dat which is set to TRUE if a data set was read in
start <- shiny::reactiveValues(dat = FALSE)
shiny::observeEvent(data2(), {
if (!is.null(data2())) {
start$dat <- TRUE
}
})
output$flag <- shiny::reactive(start$dat)
shiny::outputOptions(output, "flag", suspendWhenHidden = FALSE)
output$optDesign <- shiny::renderPlot({
# Make sure that enough dose levels are supplied
tmp1 <- as.numeric(strsplit(levels(), ";")[[1]])
if (regimen() == "Specify dose levels" & length(tmp1) > 0 & input$model == "Linear" )
shiny::validate(need(length(tmp1) > 1, 'Need at least 2 dose levels'))
if (regimen() == "Specify dose levels" & length(tmp1) > 0 & input$model == "Emax" ) {
shiny::validate(need(length(tmp1) > 2, 'Need at least 3 dose levels'))
}
if (regimen() == "Specify dose levels" & length(tmp1) > 0 & input$model == "Sigmoidal Emax" )
shiny::validate(need(length(tmp1) > 3, 'Need at least 4 dose levels'))
# error messages for some parameters if parameters are negative
if (input$model == "Emax" ) {
shiny::validate(need(input$parameter2 > 0, 'For model Emax entries needs to be positive. Please select a value >0 for parameter ED50'))
}
if (input$model == "Sigmoidal Emax" ) {
shiny::validate(need(input$parameter2 > 0, 'For model Emax Sigmoidal entries needs to be positive. Please select a value >0 for parameter ED50'))
shiny::validate(need(input$parameter4 > 0, 'For model Emax Sigmoidal entries needs to be positive. Please select a value >0 for parameter Hill'))
}
# use function 'ComputeOptimal' from Optimization.R file
x <- ComputeOptimal(input, levels = levels() , regimen = regimen(), dmin = dmin(), dmax = dmax())
optValue$doses1 <- x$res[1,]
optValue$distr1 <- x$res[2,]
optValue$pats1 <- round(x$res[2, ] * npats(), 1)
optValue$mods1 <- x$mods
optValue$optD1 <- x$optD
da <- data.frame(optValue$doses1, optValue$pats1)
op <- c("optimal design")
pl1 <- ggplot2::ggplot(
data = da, aes(x = optValue$doses1, y = optValue$pats1, group = 1)
) +
ggplot2::theme_minimal() +
ggplot2::theme(
plot.background = ggplot2::element_rect(fill = "#383838")
) +
ggplot2::theme(
legend.position = "none",
axis.text = ggplot2::element_text(colour = "white"),
panel.border = ggplot2::element_blank(),
panel.grid.major = ggplot2::element_line(colour = "#474747"),
panel.grid.minor = ggplot2::element_line(colour = "#474747", size = 0.25),
text = ggplot2::element_text(
family = "",
face = "plain",
colour = "white",
size = 12,
lineheight = 0.9,
hjust = 0.5,
vjust = 0.5,
angle = 0,
margin = margin(),
debug = FALSE
)
) +
ggplot2::geom_linerange(
ymin = 0,
ymax = optValue$pats1,
color = dosedesignR_red,
lwd = 1.2
) +
ggplot2::labs(x = "Dose", y = "Patients") +
ggplot2::ylim(0, npats() * 0.7) +
ggplot2::xlim(dmin(), dmax()) +
ggplot2::theme(
axis.text = ggplot2::element_text(size = rel(1.1)),
axis.title = ggplot2::element_text(size = rel(1.1))
) +
ggplot2::scale_colour_manual(values = c("white")) +
ggplot2::theme(
legend.text = ggplot2::element_text(size = rel(1.1)),
legend.key = ggplot2::element_rect(size = 5),
legend.margin = margin(l = -10),
legend.position = "bottom",
legend.title = ggplot2::element_blank()
) +
ggplot2::guides(
colour = guide_legend(override.aes = list(size = 1, alpha = 1, linetype = 1))
)
UserValue$doses1 <- oM()$dose
UserValue$pats1 <- oM()$patients
if (length(UserValue$doses1) == length(UserValue$pats1) && length(UserValue$pats1) > 0) {
op <- c("optimal design", "user defined design")
plotdat2 <- data.frame(doses = UserValue$doses1, pats = UserValue$pats1)
pl1 <- ggplot2::ggplot(
data = da,
ggplot2::aes(
x = optValue$doses1,
y = optValue$pats1,
group = 1
)
) +
ggplot2::geom_linerange(
ymin = 0,
ymax = optValue$pats1,
color = dosedesignR_red,
lwd = 1.2
) +
ggplot2::theme_minimal() +
ggplot2::theme(plot.background = element_rect(fill = "#383838")) +
ggplot2::theme(
legend.position = "none",
axis.text = ggplot2::element_text(colour = "white"),
panel.border = ggplot2::element_blank(),
panel.grid.major = ggplot2::element_line(colour = "#474747"),
panel.grid.minor = ggplot2::element_line(colour = "#474747", size = 0.25),
text = ggplot2::element_text(
family = "",
face = "plain",
colour = "white",
size = 12,
lineheight = 0.9,
hjust = 0.5,
vjust = 0.5,
angle = 0,
margin = margin(),
debug = FALSE
)
) +
ggplot2::labs(x = "Dose", y = "Patients") +
ggplot2::ylim(0, npats() * 0.7) +
ggplot2::theme(
axis.text = element_text(size = rel(1.1)),
axis.title = element_text(size = rel(1.1))
)
pl1 <- pl1 +
ggplot2::geom_point(
data = plotdat2,
ggplot2::aes(x = plotdat2$doses, y = plotdat2$pats, group = 1),
colour = dosedesignR_green,
size = rel(2)
) +
ggplot2::xlim(
dmin(), dmax()
) +
ggplot2::scale_colour_manual(
values = c("black", "#89D329")) +
ggplot2::theme(
legend.text = element_text(size = rel(1.1)),
legend.key = element_rect(size = 5),
legend.margin = margin(l = -10),
legend.position = "bottom",
legend.title = element_blank()
) +
ggplot2::guides(
colour = ggplot2::guide_legend(
override.aes = list(
size = c(1, 2.5),
alpha = 1,
shape = c(NA, 16),
linetype = c(1, 0)
)
)
)
}
suppressWarnings(print(pl1))
})
if (!is.null(data2())) {
output$showEstimates <- shiny::renderTable({
data2 <- data2()[selectnr()]
if (input$model == "Linear") {
tmp <- lapply(data2, function(x) {
as.data.frame(t(DoseFinding::fitMod(x$df$dose, x$df$response, model = "linear")$coefs))
})
tmp2 <- lapply(tmp, function(x) {
data.frame("Intercept" = c(input$parameter1, round(as.numeric(x[1]), 2)), "Slope" = c(input$parameter2, round(as.numeric(x[2]), 2)))})
}
if (input$model == "Emax") {
tmp <- lapply(data2, function(x) {
as.data.frame(t(DoseFinding::fitMod(x$df$dose, x$df$response, model = "emax", bnds = defBnds(max(x$df$dose))$emax)$coefs))
})
tmp2 <- lapply(tmp,function(x) {
data.frame("E0" = c(input$parameter1, round(as.numeric(x[1]), 2)),
"ED50" = c(input$parameter2, round(as.numeric(x[3]), 2)),
"Emax" = c(input$parameter3, round(as.numeric(x[2]), 2)))
})
}
if (input$model == "Sigmoidal Emax") {
tmp <- lapply(data2, function(x){
as.data.frame(t(DoseFinding::fitMod(x$df$dose, x$df$response, model = "sigEmax", bnds = defBnds(max(x$df$dose))$sigEmax)$coefs))
})
tmp2 <- lapply(tmp, function(x) {
data.frame(
"E0" = c(input$parameter1, round(as.numeric(x[1]), 2)),
"ED50" = c(input$parameter2, round(as.numeric(x[3]), 2)),
"Emax" = c(input$parameter3,round(as.numeric(x[2]), 2)),
"Hill" = c(input$parameter4, round(as.numeric(x[4]), 2)))
})
}
if (length(tmp2) > 0) {
tmp2 <- rbind.data.frame(tmp2[[1]][1, ], do.call(rbind.data.frame, lapply(tmp2, function(x) data.frame(do.call(cbind.data.frame, x[2, ]), check.names = FALSE))))
tmp2[1, ] <- paste0("<div style='width: 100%; height: 100%; z-index: 0;color: ", dosedesignR_red,"; '><span> ", tmp2[1, ], "</span></div>")
for(i in 2:(dim(tmp2)[1])){
tmp2[i, ] <- paste0("<div style='width: 100%; height: 100%; z-index: 0;color: ", data2()[[selectnr()[i - 1]]]$df$color[1], "; '><span> ", tmp2[i, ], "</span></div>")
}
tmp2
}
}, sanitize.text.function = function(x) x
)}
# Plot for the Plot Tab
output$modelFunction <- shiny::renderPlot({
shiny::validate(need(ymin() < ymax() , 'Maximum response needs to be greater than minimum response.'))
# use the 'ComputeModelFunction' function from the Visualize.R file
plotres <- ComputeModelFunction(
input = input,
tab = 1,
ymin = ymin(),
ymax = ymax(),
dmin = dmin(),
dmax = dmax(),
data = data(),
data_esti = data2(),
plot_opt = input$plot_opt,
selectnr = selectnr()
)
suppressWarnings(print(plotres))
})
# Table of dose levels
output$viewOpt <- shiny::renderTable({
dat <- matrix(c(optValue$doses1, round(optValue$pats1, 1)), nrow = 2, byrow = T)
colnames(dat) <- NULL
rownames(dat) <- c("Dose", "Patients")
dat
}, digits = 1, align = NULL, rownames = TRUE, colnames = FALSE)
output$viewEff <- shiny::renderTable({
# use the 'ComputeEfficiency' function from the Optimization.R file
dat <- ComputeEfficiency(UserValue, optValue, input, 1, npats = npats())
if (dim(dat)[1] == 3 & dim(dat)[2] == 1) {
colnames(dat) <- NULL
rownames(dat) <- c("Patients", "Efficiency [%]", "Additional patients needed")
} else if (dim(dat)[1] == 1 & dim(dat)[2] == 1) {
colnames(dat) <- NULL
rownames(dat) <- c("Information:")
}
dat
}, digits = 1, align = NULL, rownames = TRUE, colnames = FALSE)
# update the labels of the numeric input's depending on the selected model
shiny::observeEvent(input$model, {
if (input$model == "Linear") {
shiny::updateNumericInput(session, "parameter1", label = "Intercept")
shiny::updateNumericInput(session, "parameter2", label = "Slope")
} else if (input$model == "Emax") {
shiny::updateNumericInput(session, "parameter1", label = "E0")
shiny::updateNumericInput(session, "parameter2", label = "ED50")
shiny::updateNumericInput(session, "parameter3", label = "Emax")
} else if (input$model == "Sigmoidal Emax") {
shiny::updateNumericInput(session, "parameter1", label = "E0")
shiny::updateNumericInput(session, "parameter2", label = "ED50")
shiny::updateNumericInput(session, "parameter3", label = "Emax")
shiny::updateNumericInput(session, "parameter4", label = "Hill")
}
})
#### create undo button for the standardize button ####
undo <- shiny::eventReactive(input$go_stand, {
tmp <- c(
shiny::isolate(input$parameter1),
shiny::isolate(input$parameter2),
shiny::isolate(input$parameter3),
shiny::isolate(input$parameter4)
)
tmp
})
shiny::observeEvent(input$undoButton, {
shiny::req(undo())
tmp <- undo()
shiny::updateNumericInput(session, "parameter1", value = tmp[1])
shiny::updateNumericInput(session, "parameter2", value = tmp[2])
shiny::updateNumericInput(session, "parameter3", value = tmp[3])
shiny::updateNumericInput(session, "parameter4", value = tmp[4])
})
# Standardize Button
shiny::observeEvent(input$go_stand, {
req(undo())
if (!is.null(input$model)) {
if (input$model == "Linear") {
if (!is.null(optValue$doses1)) {
tmp <- DoseFinding::Mods(
linear = NULL,
maxEff = ymax(),
doses = optValue$doses1,
placEff = 0
)
shiny::updateNumericInput(session, "parameter2", value = as.numeric(tmp$linear[2]))
}
}
if (input$model == "Emax") {
if (!is.null(optValue$doses1)) {
tmp <- DoseFinding::Mods(
emax = input$parameter2,
maxEff = ymax(),
doses = optValue$doses1,
placEff = 0
)
shiny::updateNumericInput(session,"parameter3", value = as.numeric(tmp$emax[2]))
}
}
if (input$model == "Sigmoidal Emax") {
if (!is.null(optValue$doses1)) {
tmp <- DoseFinding::Mods(
sigEmax = c(input$parameter2, input$parameter4),
maxEff = ymax(),
doses = optValue$doses1,
placEff = 0
)
shiny::updateNumericInput(session, "parameter3", value = as.numeric(tmp$sigEmax[2]))
}
}
}
})
# reactive object 'settings' to save all parameters
# could be reduced without the model distinctive
settings <- shiny::reactive({
nrPanel()
button()
shiny::req(shiny::isolate(input$model), nrPanel())
list(
'model' = input$model,
'parameter' = c(
shiny::isolate(input$parameter1),
shiny::isolate(input$parameter2),
shiny::isolate(input$parameter3),
shiny::isolate(input$parameter4)
),
'levels' = oM(),
'showParameter' = input$parambox
)
})
return(
list(
parameter1 = shiny::reactive({input$parameter1}),
parameter2 = shiny::reactive({input$parameter2}),
parameter3 = shiny::reactive({input$parameter3}),
parameter4 = shiny::reactive({input$parameter4}),
send_design_button = shiny::reactive({input$send_design}),
optValdoses = shiny::reactive({optValue$doses1}),
optValpats = shiny::reactive({optValue$pats1}),
UserValdoses = shiny::reactive({UserValue$doses1}),
UserValpats = shiny::reactive({UserValue$pats1}),
model = shiny::reactive({input$model}),
setting = shiny::reactive({settings()})
)
)
}
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.