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 framechoices_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()