Search code examples
rshinymarkdownselectinput

How can I create a conditional selectInput widget in R Markdown?


The purpose is to choose a county from a state. I first create a selectInput widget for choosing a state. Then I create a selectInput widget for choosing a county from the selected state. In an R Markdown, the code is as follows:

inputPanel(
   selectInput(inputId = "State", label = "Choose a state:", choices = state.name),
   selectInput(inputId = "County", label = "Choose a county:", choices = input.State)
)

I guess the use of input.State is problematic, but I don't have any other idea.

Thanks for your time!


Solution

  • There are a number of ways to create conditional/dynamic UI in Shiny (see here). The most straightforward is usually renderUI. See below for a possible solution for you. Note that this requires Shiny so if you’re using R Markdown make sure to specify runtime: shiny in the YAML header.

    library(shiny)
    
    # I don't have a list of all counties, so creating an example:
    county.name = lapply(
      1:length(state.name),
      function(i) {
        sprintf("%s-County-%i",state.abb[i],1:5)
      }
    )
    names(county.name) = state.name
    
    shinyApp(
    
      # --- User Interface --- #
    
      ui = fluidPage(
    
        sidebarPanel(
          selectInput(inputId = "state", label = "Choose a state:", choices = state.name),
          uiOutput("county")
        ),
    
        mainPanel(
          textOutput("choice")
        )
    
      ),
    
      # --- Server logic --- #
    
      server = function(input, output) {
        output$county = renderUI({
          req(input$state) # this makes sure Shiny waits until input$state has been supplied. Avoids nasty error messages
          selectInput(
            inputId = "county", label = "Choose a county:", choices = county.name[[input$state]] # condition on the state
          )
        })
    
        output$choice = renderText({
          req(input$state, input$county)
          sprintf("You've chosen %s in %s",
                  input$county,
                  input$state)
        })
      }
    
    )
    

    Hope this helps!