隔离conditionalPanel闪亮

时间:2015-04-17 12:59:34

标签: r shiny

我有一个shiny标签,用户可以通过selectInput选择多个参数。选择之后,用户单击actionButton并在服务器端进行一系列计算。根据结果​​和选择,应该显示一个或多个conditionalPanels。问题是,一旦用户更改了选择,显示的conditionalPanel会立即更改。但是,我希望仅在用户再次按下actionButton并且服务器端的计算已更新后才评估条件。有没有办法将conditionalPanel上的actionButton条件联系起来?

这是我能想出的最好的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)

因此,假设我启动应用并选择SLengthSWidth,点击Go - 按钮并获取点图。然后我想显示SLengthPLength,因此我从选择字段中删除了SWidth,同时我得到了两个直方图,每个直方图都有一个。条件面板立即响应input$variable的更改,而服务器脚本中的观察者仍在等待我按下按钮。显然,这不是用户期望的行为。预期的行为是,只有按下Go - 按钮才能评估条件面板的条件。有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:0)

在服务器端做条件怎么样?

    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)         

编辑:使用submitButton

添加了另一个选项

您还可以使用submitButton()并将observeEvent()附加到input$variable()。 “包含提交按钮的表单在输入更改时不会自动更新其输出,而是等到用户明确单击提交按钮。” 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)