R Shiny selectInput dependent on another input

Symbol of coding on a computer screen
Symbol of coding on a computer screen Method 1 – example code

In the example code below, the variables are as follows:

Sample data table for choices

We create a (really) simple two-column data table, 'category' and 'items' for the selection choices, called 'choices_table'.

FIRST selectInput
  • Name (ID): "choose_category"
  • Choices: choices_table$category  (‘category’ column from the data frame choices_table)
  • Result (output = user’s selection): input$choose_category
SECOND selectInput
  • Name (ID): "choose_item"
  • Choices: choices_table$items (‘items’ column from the data frame choices_table, filtered by the user’s choice of the first selectInput).
  • The output variable name (ID): "cat_choice" is the reactive variable which takes the first selectInput choice and filters the possible choices for the second selectInput.
  • Result (output = user’s choice): input$choose_item
Table output of user’s choices
  • A table showing the user’s choices is created using an output variable, name "tb_chosen".
  • By using the reactive function renderTable(), we can capture the dynamic outputs of the selectInput controls, and filter the data to display the user’s choices: input$choose_category, input$choose_item.
  • The table is added to the layout by using tableOutput("table_ID").

Copy and paste the code below into RStudio and save the file as an R Markdown file, .Rmd.

---
title: "Shiny selectInput based on another selectInput"
runtime: shiny
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, error=TRUE)

```

```{r create_table_of_choices, eval=TRUE}

# table of choices for the selectInput controls
# note there's a duplicate item 'Pear'

  x <- c("Fruit","Animal","Animal","Fruit","Fruit","Animal","Animal","Fruit")
  y <- c("Pear","Dog","Cat","Apple","Banana","Monkey","Giraffe","Pear")

# bind x and y into a dataframe with two columns, using cbind() (column bind), and as.data.frame so we can apply unique.
  choices_table <- as.data.frame(cbind(x,y))
  colnames(choices_table) <- c("category","items")

# look at the table of choices
#   choices_table
#   choices_table$category

```

```{r selectInputs, eval=TRUE, error=TRUE}

# create and display the FIRST selectInput control

selectInput(inputId="choose_category",
            label="Select category",
            choices=unique(choices_table$category),
            selected="Animal")

# display the second selectInput control - note that we can
#  define the output further down in the R script, R will find the output

uiOutput("cat_choice")

#display the table with the user's choices from the selectInputs
tableOutput("tb_chosen")

output$tb_chosen <- renderTable(subset(choices_table,
 choices_table$category==input$choose_category & 
 choices_table$items==input$choose_item), rownames = TRUE)

# The SECOND selectInput control
# create an output variable based on the first control
# wrap the variable in a reactive function renderUI() 
#  so that we can capture the dynamic output from
#  the first selectInput.
# We've used 'unique' when subsetting the choices
#  because we have duplicate items

output$cat_choice <- renderUI({
  selectInput(inputId="choose_item",
            label="Select item",
            choices=unique(choices_table 
            [choices_table$category==input$choose_category,"items"]))
})

```

>> On the next page, we show Method 2, using observe() with updateSelectInput()

Pages: 1 2 3 4