使用条件selectInput的RenderUI,在Shiny

时间:2018-04-17 09:03:24

标签: r shiny

我正在尝试使用:

构建一个Shiny界面
  1. 主选择器,决定:
  2. 显示哪个子菜单(输入),决定:
  3. 要显示的后续输入数量
  4. 这是一个可重复性最小的例子。

    如果"第一"从主选择器中选择,然后存在具有两种可能性[1,2]的子菜单。这些可能性导致构建1或2个后续输入。所以这些可能性:

    First possibilities

    如果" Second"从主选择器中选择,然后存在具有两种可能性[3,4]的子菜单。这些可能性导致建立3或4个后续输入。

    Second possibilities

    ui <- fluidPage(
      radioButtons(inputId="main_selector",label=h5('Select menu'),
                   choices = list('First','Second'),selected='First'),
      uiOutput("ui_selected")
    )
    
    server <- function(input, output, session) {
    
      build_inputs <- function(choices){
        output = tagList()
        for(i in 1:choices){
          output[[i]] = tagList()
          output[[i]][[1]] = numericInput(inputId =  paste0(i),
                                          label =  paste0(i),
                                          value = i)
        }
      }
    
    # Are these reactive elements necessary? Should they be in the renderUI below?
      first_submenu <- reactive({
        input$first_submenu
      })
      second_submenu <- reactive({
        input$second_submenu
      })
    
      output$ui_selected <- renderUI({
    
        if (input$main_selector == 'First'){
        selectInput(inputId = "first_submenu", label="First submenu",
                    choices=list(1,2))
    
          choices_1 <- first_submenu()
          # Build a list of inputs dependent on the choice above
          output <- build_inputs(choices_1)
    
        } else if (input$main_selector == 'Second'){
          selectInput(inputId = "second_submenu", label="Second submenu",
                      choices=list(3,4))
    
          choices_2 <- second_submenu()
          # Build a list of inputs dependent on the choice above
          output <- build_inputs(choices_2)
    
        # Return output as output$ui_selected element 
        output
      })
    }
    
    shinyApp(ui, server)
    

    我收到的错误是警告:长度为0的参数错误。我相信这是因为你无法从renderUI元素中调用first_submenu的结果 - 但我不知道如何正确构造我的代码。

1 个答案:

答案 0 :(得分:1)

我不确定这是否是你所追求的。主要问题是你的函数build_inputs没有返回任何东西。第二个问题是来自selectInput的选择不是数字,因此您需要事先转换它们。与您提到的错误相关的另一个小问题是,您要呈现的元素同时存在,因此在input$first_submenu上添加条件会触发错误(即使它是NULL几毫秒),所以它(几乎总是)好的做法是处理可能为空的输入。我做的最后一件事是为最后一层动态输入添加另一个uiOutput。希望这会有所帮助。

ui <- fluidPage(
  radioButtons(inputId="main_selector",label=h5('Select menu'),
               choices = list('First','Second'),selected='First'),
  uiOutput("ui_selected"),
  uiOutput("ui_numeric_inputs")
)

server <- function(input, output, session) {

  build_inputs <- function(choices) {
    output = tagList()
    for(i in 1:choices){
      output[[i]] = tagList()
      output[[i]][[1]] = numericInput(inputId =  paste0(i),
                                      label =  paste0(i),
                                      value = i)
    }
    return(output)
  }

  output$ui_selected <- renderUI({

    if (input$main_selector == 'First'){
      selectInput(inputId = "first_submenu", label="First submenu",
                  choices=c(1,2))
    } else if (input$main_selector == 'Second'){
      selectInput(inputId = "second_submenu", label="Second submenu",
                  choices=list(3,4))
    }
  })

  output$ui_numeric_inputs <- renderUI({
    if (input$main_selector == 'First' && 
(!is.null(input$first_submenu))) {
      build_inputs(as.numeric(input$first_submenu))
    } else if (input$main_selector == 'Second' && 
(!is.null(input$second_submenu))){
      build_inputs(as.numeric(input$second_submenu))
    }
  })
}

shinyApp(ui, server)