简体   繁体   English

在闪亮的条件面板中隔离

[英]isolate conditionalPanel in shiny

I've got a shiny tab where the user can select several parameters via selectInput . 我有一个shiny标签,用户可以在其中通过selectInput选择多个参数。 After the selection, the user clicks on an actionButton and a bunch of calculations happen on the server side. 选择之后,用户单击一个actionButton ,服务器端将进行大量计算。 Depending on both the results and the selections, one or several conditionalPanels are supposed to be shown. 根据结果​​和选择,应该显示一个或几个conditionalPanels The problem is that once the user changes the selection, the displayed conditionalPanel changes immediately. 问题在于,一旦用户更改了选择,显示的conditionalPanel就会立即更改。 However, I'd like the conditions only to be evaluated after the user has pushed the actionButton again and the calculations on the server side have been updated. 但是,我希望仅在用户再次按下actionButton并更新服务器端的计算之后才能评估条件。 Is there a way to tie the condition of the conditionalPanel on an actionButton ? 有没有办法将conditionalPanel的conditionalPanel绑定到actionButton

Here is the best MWE I could come up with to capture all the nuances (actually, the dependency of the conditional panels on some server results is still missing here): 这是我能想到的最好的MWE,可以捕获所有细微差别(实际上,这里仍然缺少条件面板对某些服务器结果的依赖性):

library(shiny)
library(plyr)

ui <- fluidPage(
  selectInput("variable", "Variable:",
              c("SLength" = "Sepal.Length",
                "SWidth" = "Sepal.Width",
                "PLength" = "Petal.Length",
                "PWidth" = "Petal.Width",
                "Species" = "Species"),
              multiple = TRUE),
  br(),
  actionButton("goButton", "Go!"), 
  hr(),
  conditionalPanel(condition = "input['variable'].length == 1",
                   plotOutput("oneplot")),
  conditionalPanel(condition = "input['variable'].length == 2",
                   plotOutput("twoplot"))
)

server <- function(input, output){
  v <- reactiveValues(plot.type = NULL)

  observeEvent(input$goButton, {
    if (is.null(input$variable)) return(NULL)
    if ("Species" %in% input$variable & length(input$variable > 1)){
      sec.var <- input$variable[which(input$variable != "Species")]
      v$summary <- ldply(by(iris[,sec.var], iris$Species, mean))
      v$summary[,1] <- as.factor(v$summary[,1])
    } else if ("Species" %in% input$variable)
      v$summary <- table(iris$Species) else
        v$summary <- iris[,input$variable]
  })

  output$oneplot <- renderPlot({
    if (is.null(v$summary)) return(NULL)
    if (input$variable == "Species") return(NULL)
    hist(v$summary)
  })

  output$twoplot <- renderPlot({
    if (is.null(v$summary)) return(NULL)
    plot(v$summary)
  })
}

shinyApp(ui, server)

So let's say I start the app and select SLength and SWidth , click the Go -Button and get a dotplot. 假设我启动了该应用程序,然后选择SLengthSWidth ,单击Go -Button并得到一个点图。 Then I'd want to show SLength vs. PLength , so I delete SWidth from the selection field and the same moment I get two histograms, one for each of the previous selections. 然后,我想显示SLength vs. PLength ,所以我从选择字段中删除了SWidth ,同时获得了两个直方图,每个先前的选择一个。 The conditional panel immediately reacts to the change of input$variable , while the observer within the server script is still waiting for me to push the button. 条件面板会立即对input$variable的更改作出反应,而服务器脚本中的观察者仍在等待我按下按钮。 Obviously, that's not the behaviour the user would expect. 显然,这不是用户期望的行为。 The expected behaviour would be that the evaluation of the conditions of the conditional panels only happens upon pushing the Go -button. 预期的行为是对条件面板条件的评估仅在按下“ Go按钮时进行。 Is there a way to achieve this? 有没有办法做到这一点?

How about doing condition on server side? 在服务器端做条件怎么样?

    library(shiny)
    library(plyr)

    ui <- fluidPage(
      selectInput("variable", "Variable:",
                  c("SLength" = "Sepal.Length",
                    "SWidth" = "Sepal.Width",
                    "PLength" = "Petal.Length",
                    "PWidth" = "Petal.Width",
                    "Species" = "Species"),
                  multiple = TRUE),
      br(),
      actionButton("goButton", "Go!"), 
      hr(),
       plotOutput("oneplot")
     # conditionalPanel(condition = "input['variable'].length == 1",
     #                  plotOutput("oneplot")),
     # conditionalPanel(condition = "input['variable'].length == 2",
      #                 plotOutput("twoplot"))
    )

    server <- function(input, output){
      v <- reactiveValues(plot.type = NULL)

      observeEvent(input$goButton, {
        if (is.null(input$variable)) return(NULL)
        if ("Species" %in% input$variable & length(input$variable > 1)){
          sec.var <- input$variable[which(input$variable != "Species")]
          v$summary <- ldply(by(iris[,sec.var], iris$Species, mean))
          v$summary[,1] <- as.factor(v$summary[,1])
        } else if ("Species" %in% input$variable)
          v$summary <- table(iris$Species) else
            v$summary <- iris[,input$variable]
      })

      output$oneplot <- renderPlot({
        #Added actionButton dependency here
        input$goButton
        isolate({
        if(length(input$variable)== 1) {
            if (is.null(v$summary)) return(NULL)
            if (input$variable == "Species") return(NULL)
            hist(v$summary)
        }
        else {
             if (is.null(v$summary)) return(NULL)
            plot(v$summary)
        }
        })
      })

      #output$twoplot <- renderPlot({

        #if (is.null(v$summary)) return(NULL)
        #plot(v$summary)

      #})
    }

shinyApp(ui, server)         

EDIT: Added another option by using submitButton 编辑:通过使用submitButton添加了另一个选项

You can also use submitButton() and attach observeEvent() to input$variable() . 您还可以使用submitButton() ,并将observeEvent()附加到input$variable() "Forms that include a submit button do not automatically update their outputs when inputs change, rather they wait until the user explicitly clicks the submit button." “包含输入按钮的表单不会在输入发生更改时自动更新其输出,而是会等到用户显式单击提交按钮之后。” submitButton 提交按钮

library(shiny)
library(plyr)

ui <- fluidPage(
  selectInput("variable", "Variable:",
              c("SLength" = "Sepal.Length",
                "SWidth" = "Sepal.Width",
                "PLength" = "Petal.Length",
                "PWidth" = "Petal.Width",
                "Species" = "Species"),
              multiple = TRUE),
  br(),
  submitButton("Go!"), 
  hr(),
  conditionalPanel(condition = "input['variable'].length == 1",
                   plotOutput("oneplot")),
  conditionalPanel(condition = "input['variable'].length == 2",
                   plotOutput("twoplot"))
)

server <- function(input, output){
  v <- reactiveValues(plot.type = NULL)

  observeEvent(input$variable, {
    if (is.null(input$variable)) return(NULL)
    if ("Species" %in% input$variable & length(input$variable > 1)){
      sec.var <- input$variable[which(input$variable != "Species")]
      v$summary <- ldply(by(iris[,sec.var], iris$Species, mean))
      v$summary[,1] <- as.factor(v$summary[,1])
    } else if ("Species" %in% input$variable)
      v$summary <- table(iris$Species) else
        v$summary <- iris[,input$variable]
  })

  output$oneplot <- renderPlot({
    if (is.null(v$summary)) return(NULL)
    if (input$variable == "Species") return(NULL)
    hist(v$summary)
  })

  output$twoplot <- renderPlot({
    if (is.null(v$summary)) return(NULL)
    plot(v$summary)
  })
}

shinyApp(ui, server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM