Dropdown options based on another widget

I'm new to R and shiny (coming from Python), so please bear with me. Using the example below, I simply want to restrict the options available in the selectizeInput widget based on what is selected from the first widget (the radio buttons). For example, if the radio button option of "A class" is selected, then I want the dropdown box to only show the two "A class" funds: Fund A and Fund B. Conversely, if "B class" is selected, the dropdown should only show funds C & D.

library(shiny)

series_choices = c("A class", "B class")
fund_choices = c("Fund A", "Fund B", "Fund C", "Fund D")
fund_series = c("A class", "A class", "B class", "B class")

# Shiny app ----

ui <- fluidPage(
  
  titlePanel("Fund Comparison"),
  
  sidebarLayout(
    
    # Sidebar panel for inputs ----
    sidebarPanel(
      
      # Series selector
      radioButtons(inputId = "series_selector",
                   label = "Series:",
                   choices = series_choices,
                   inline=TRUE,
                   selected = "A class"),
      
      # Fund selector
      selectizeInput(inputId = "funds_selector",
                     label = "Funds:",
                     choices = fund_choices,
                     multiple = TRUE),

    ),
    
    # Main panel for displaying outputs ----
    mainPanel(
      
      # [Some charts coming later]
      
    )
  )
)

server <- function(input, output) {

}

# Create Shiny app ----
shinyApp(ui, server)

Try the code below, explained inline. If anything is unclear, let me know and I will be happy to elaborate.


library(shiny)
series_choices = c("A class", "B class")
fund_choices = c("Fund A", "Fund B", "Fund C", "Fund D")
fund_series = c("A class", "A class", "B class", "B class")

# Replace your fund_* variables with a data.frame, since you
# want to filter one vector based on another. Not exactly necessary,
# but will keep things a bit cleaner if you add other fund-related
# information.
funds <-
  data.frame(
    choices = c("Fund A", "Fund B", "Fund C", "Fund D"),
    series = c("A class", "A class", "B class", "B class"),
    stringsAsFactors = FALSE
  )

# Shiny app ----

ui <- fluidPage(titlePanel("Fund Comparison"),
                
                sidebarLayout(# Sidebar panel for inputs ----
                              sidebarPanel(
                                # Series selector
                                radioButtons(
                                  inputId = "series_selector",
                                  label = "Series:",
                                  choices = series_choices,
                                  inline = TRUE,
                                  selected = "A class"
                                ),
                                
                                # Fund selector
                                selectizeInput(
                                  inputId = "funds_selector",
                                  label = "Funds:",
                                  # We can initialize this as NULL because
                                  # we will update in the server function.
                                  choices = NULL,
                                  multiple = TRUE
                                ),
                                
                              ),
                              
                              # Main panel for displaying outputs ----
                              mainPanel()))# [Some charts coming later]))))))
# I've added the optional "session" variable to the server function.
# this is necessary for Shiny applications which will have different behavior
# based upon user inputs. In this case, the different behavior is changing
# the selectizeInput choices.
server <- function(input, output, session) {
  # Whatever is inside `observeEvent()` will be triggered each time the first
  # argument undergoes a change in value. In this case, that means whenever
  # the user changes the radio button value.
  observeEvent(input$series_selector,
               {
                 # Use this function to update the choices for the user.
                 # First argument is session, next the input to update,
                 # and third the new choices. Here, I'm filtering the
                 # previously made data.frame to based on the series column,
                 # and returning the choices column. 
                 # `drop=TRUE` makes it explicit that I want a vector returned.
                 updateSelectizeInput(session, input = "funds_selector",
                                      choices = funds[funds$series %in% input$series_selector,
                                                      "choices", drop = TRUE])
               })
}

# Create Shiny app ----
shinyApp(ui, server)
1 Like

@smingerson Brilliantly explained and works perfectly, thank you so much! May I ask what you think is/are the best resource(s) for someone like myself getting start in shiny?

Sure!

This is a book in progress by Hadley Wickham. It already does an excellent job explaining things. There's a Shiny topic called modules which I could never get my head around -- every time I tried to use them I had to pour over several examples and go by trial and error. After reading the section on modules in the book, they seemed much clearer to me, although I haven't had a chance to apply that knowledge.

This is a great list by Dean Attali. This is a list with code snippets of how to get things done in Shiny. It's a great reference for things I do frequently, and gives you a good idea of how flexible Shiny is.

This is another great list. Instead of examples, it provides resource lists for Shiny -- learning materials, packages which use Shiny, and more. This is another great way to discover what is possible in Shiny.

The last resource is RStudio's Shiny website. There are user showcases with code to see how to accomplish certain things, as well as minimal examples which demonstrate particular features. For your question, I almost could have just linked this example.

There are plenty of other great resources such as blog posts and SO questions. The first time I want to do something in Shiny I don't know how to, I check Dean Attali's list. Then I try a couple different ways of googling my question. That typically leads to either a SO question, a blog post, or an R package.

2 Likes

@smingerson Can't thank you enough! :raised_hands: Especially excited about starting to read your first recommendation from the man himself! :grin:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.