【发布时间】:2020-08-07 15:56:16
【问题描述】:
我正在开发一个 Shiny 应用程序,它可以生成各种图表并允许用户更改图形参数。为此,我使用了selectInput、numericInput 和checkboxInput 函数的组合在生成图后(conditionalPanel)。我打包了代码,以便被动地计算用于图形的data.frame(以允许在绘图之前进行灵活的子集化)。一切都很好,但是当我想更新一些图形参数(例如通过selectInput 使用的颜色)时,代码会崩溃,因为它在我选择所有必要的颜色之前过早地评估(即当需要 4 种颜色时,代码选择第一种颜色后立即中断)。
我知道 debounce 延迟评估的功能,但我不想使用它,因为:
- 我喜欢更新其他参数时图表的即时变化
- 颜色的选择可能需要一些时间,因此很难设置预定的延迟时间/时间间隔
一种解决方案是添加有条件显示的actionButton(连同其他图形参数)来调节无功输入值的触发(见下文)。这并不理想,因为更改参数后,我需要单击更新来更新图形。另外,我不确定这将如何工作,因为km_graph 已经是一个反应性绘图对象。或者,是否有专门调节selectInput 的解决方案,以便在选择所有颜色之前不对其进行评估?
我阅读了有关此问题的几篇文章,但找不到适用于我的代码设计的解决方案。我将尝试写下我的ui 和server 的部分,以了解我正在尝试做什么:
ui.R
# ...
mainPanel(
plotOutput("km_graph"),
# Conditional panel prompted only after the km_graph is generated
conditionalPanel(
condition = "output.km_graph" ,
checkboxInput("km_risk", label="Show risk table", F),
selectInput("km_medline", label = "Mark median survival",
selected = "hv",
choices = c("None" = "none",
"Horizontal-Vertical" = "hv",
"Vertical" = "v",
"Horizontal" = "h")),
sliderInput("km_xlim", label="days", value = 6000, min = 10, max=10000),
selectInput("km_pal", "Select colors", multiple = T,
selectize = T,
selected = "jco",
choices = list(`Pre-made palettes` = list("npg","aaas", "lancet", "jco",
"ucscgb", "UChicago",
"simpsons", "rickandmorty")
`Individual colors` = as.list(color_choices))
)
# Need to find a way to prevent evaluating before all the colors are selected for km_pal
# Maybe another actionButton() here to update graph after all the parameters are selected?
服务器.R
#...
# km_results() is the reactive object containing survival analysis results
# km_dat() is the reactive data frame used in the analyses
output$km_graph <- renderPlot({
survminer::ggsurvplot(km_results(), data = km_dat(),
pval = input$km_pval,
pval.method = input$km_pval,
risk.table = input$km_risk,
conf.int = input$km_confint,
surv.median.line = input$km_medline,
break.time.by = input$km_breaktime,
legend="right",
xlim=c(0, input$km_xlim),
palette = input$km_pal) ###### This breaks due to premature evaluation
})
完整的代表
shinyApp(
ui = basicPage(
selectInput("dat", "Select data",
selected = "iris", choices = c("iris")),
actionButton("go", "Go!"),
plotOutput("plot"),
conditionalPanel(
h3("graphing options"),
condition = "output.plot",
checkboxInput("plot_point", "Show points", T),
selectizeInput("plot_colors", "Select colors", selected="jco",
choices = list(`premade`=list("jco", "npg"),
`manual`=list("red", "black", "blue")))
)
),
server = function(input, output) {
dat <- reactive({
if(input$dat == "iris") iris
})
output$plot <- renderPlot({
req(input$go)
ggpubr::ggscatter(dat(), "Sepal.Length", "Sepal.Width",
color="Species", palette=input$plot_colors)
})
}
)
感谢您的见解!
【问题讨论】:
-
请发布一个可重现的最小示例。
-
用reprex更新了帖子。