防止Shiny selectInput在更新反应式绘图时过早地评估。

我正在开发一个Shiny应用,它可以生成各种图,并允许用户更改图形参数。为此,我使用了以下组合 selectInput, numericInputcheckboxInput 职能 之后 剧情的生成 (conditionalPanel). 我将代码打包,使 data.frame 用于图表的颜色是被反应式计算的(以便在绘制前灵活地进行子集)。一切都很好,但是当我想更新一些图形参数时(例如通过 selectInput),代码会崩溃,因为它在我选择所有必要的颜色之前就过早地评估了(例如,当需要4种颜色时,代码在选择第一种颜色后就中断了)。

我知道 debounce 函数来延迟评估,但我不想使用它,因为。

  • 我喜欢当我更新其他参数时图形的即时变化
  • 颜色的选择可能需要一定的时间,所以很难设定一个预定的延迟时间间隔。

一个解决方案是在一个页面上添加一个 actionButton 有条件地显示(与其他图形参数一起)以调节反应输入值的发射(见下文)。这并不理想,因为在改变参数后,我需要点击更新来更新图形。另外,我也不知道这样做是如何工作的,因为我的 km_graph 已经是一个反应式的情节对象。另外,是否有一种解决方案可以调节 selectInput 特别是在选择所有颜色之前,它不会被评估?

我读了几个关于这个问题的帖子,但我找不到一个适合我的代码设计的解决方案。我将试着把我的 uiserver 来说明我想做的事情。

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
              
        
    })

完整的Reprex

    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)
                
            })
            
        }
    )
    

谢谢你的见解!我正在开发一个Shiny应用,它可以生成各种图,并允许用户改变图形参数。

解决方案:

我不确定我是否完全理解,但你可以例如通过 plot_colors 输入到一个反应式变量中,由一个动作按钮 “应用颜色 “触发?

(你需要添加 multiple = TRUEselectizeInput的参数)

下面是一个基于你的reprex的代码例子。

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",
                     multiple = TRUE,
                     choices = list(`premade`=list("jco", "npg"),
                                    `manual`=list("red", "black", "blue"))),

      actionButton(inputId = "apply", label = "Apply colors")

    )

  ),

  server = function(input, output) {

    dat <- reactive({

      if(input$dat == "iris") iris

    })

    params_curve <- shiny::eventReactive(eventExpr = input$apply, 
                                         {
                                           return(list(colors = input$plot_colors))
                                         },
                                         ignoreNULL = F, 
                                         ignoreInit = F
    )

    output$plot <- renderPlot({

      req(input$go)

      ggpubr::ggscatter(dat(), "Sepal.Length", "Sepal.Width",
                        color="Species", palette=params_curve()$colors)

    })



  }
)

如果你选择 “红色”、”黑色 “和 “蓝色”,那么你的 “红色 plot_colors 变量为3,所以,剧情就呈现出来了。

给TA打赏
共{{data.count}}人
人已打赏
未分类

从一个大的StorageFile中获取base64字符串并将其存储在另一个StorageFile中。

2022-9-8 20:21:39

未分类

将特定范围的单元格导出为PDF - Google Sheets。

2022-9-8 20:21:41

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索