R Shiny:将多个连续反应传递给selectInput

时间:2014-10-08 23:55:12

标签: r shiny

我一直在努力扩展Ramnath(使用updateSelectInput)发布的第二个解决方案,该问题最初发布在R shiny passing reactive to selectInput choices。我想允许用户从分层系列输入中选择输入,其中每个选择中的选择更新下一个选择中的可能值。作为一个例子,在下面我通过简单地添加第三个输入来修改Ramnath的代码,该输入列出了在第二个输入中选择的变量的值。此示例基于mtcarsiris数据集,并在R v 3.1.1和RStudio v 0.98.1062上运行。它不会引发错误,但您会发现我仍然坚持如何添加第二个reactive(),它将input$datasetinput$column的组合作为输入。

library(shiny)

runApp(list(

  ui = bootstrapPage(
    selectInput('dataset', 'Choose data set', c('mtcars', 'iris')),
    selectInput('columns', 'Choose variable', ""),
    selectInput('values', 'Show values', "")
  ),

  server = function(input, output, session){

    # updates variable names based on selected dataset 
    outVar = reactive({
      names(get(input$dataset))
    })

    # i want this to update the values of the selected variable
    outVar2 = reactive({
      sort(unique(get(input$dataset)[, 2]))  # this works but of course I don't want the second variable every time
      #sort(unique(get(input$dataset)[, input$columns]))   # this fails but this is the idea I'm after
    })

    # i want these to update the UI based on the reactive output above 
    observe({
      updateSelectInput(session, "columns", choices = outVar())
      updateSelectInput(session, "values", choices = outVar2())
    })       
  }
))

1 个答案:

答案 0 :(得分:4)

回应我的第一个问题。似乎这已经过时了,但由于过去一周我一直在玩Shiny,我想我会帮助直接回答这个问题。

要直接回答问题,{​​{1}}语句不会失败,它是observe语句。由于outVar()outVar2()都在observe语句中,因此observe语句将在任一变量更新时运行。因此,当更改第二个selectInputinput$columns变量)时,实际上会导致第一个selectInput通过updateSelectInput(session, "columns", choices = outVar())进行更新。

然后将列下拉列表重置为原始选项,使其看起来好像应用程序已损坏。要以慢动作查看此内容,我建议在browser()语句中添加observe调用,以了解代码的执行方式:

observe({
  browser()
  updateSelectInput(session, "columns", choices = outVar())
  updateSelectInput(session, "values", choices = outVar2())
})

总的来说,我将observe语句分解为2个observeEvent语句(当我更改数据集时,只将语句分成两个单独的observe语句时出错。通过将updateSelectInput函数包装在observeEvent中,只有当必要的输入实际更新时,它们才会尝试运行,如下所示:

library(shiny)

runApp(list(

  ui = bootstrapPage(
    selectInput('dataset', 'Choose data set', c('mtcars', 'iris')),
    selectInput('columns', 'Choose variable', ""),
    selectInput('values', 'Show values', "")
  ),

  server = function(input, output, session){

    # updates variable names based on selected dataset 
    outVar = reactive({
      names(get(input$dataset))
    })

    # i want this to update the values of the selected variable
    outVar2 = reactive({
      if (input$columns == "") return()
      sort(unique(get(input$dataset)[, input$columns]))
    })

    # create separate observeEvents to 
    observeEvent(input$dataset, {
      updateSelectInput(session, "columns", choices = outVar())
    })

    observeEvent(input$columns, {
      updateSelectInput(session, "values", choices = outVar2())
    })

  }
))