It sounds like you want both a reactive component and dynamic UI.
We'll use the built-in dataset mtcars. This is nice because the carb variable has a range of 4 1 2 3 6 8 and the variable gear has a range 4 3 5. And most importantly, when carb == 1, there are only gears 4 and 3.
Here's a reproducible example:
library(shiny)
library(tidyverse)
ui <- fluidPage(
selectizeInput(
inputId = "filter_carb",
label = "Filter 1: carb",
selected = 1,
choices = unique(mtcars$carb)
),
uiOutput("filter_gear"),
mainPanel(
verbatimTextOutput("table")
)
)
server <- function(input, output) {
filtered_data <- reactive({
mtcars %>%
filter(carb == input$filter_carb)
})
output$filter_gear <- renderUI({
selectizeInput("filter_gear", "Filter 2: gear", unique(filtered_data()$gear))
})
output$table <- renderPrint({
filtered_data() %>%
filter(gear %in% input$filter_gear) %>%
print()
})
}
shinyApp(ui = ui, server = server)
There are few key components. First, in server we have
filtered_data <- reactive({
mtcars %>%
filter(carb == input$filter_carb)
})
This means that every time input$filter_carb changes, filter_data will update with the new filtered dataset.
Next, we want to dynamically render an input UI based on our filtered data:
output$filter_gear <- renderUI({
selectizeInput("filter_gear", "Filter 2: gear", unique(filtered_data()$gear))
})
This will be the gear filter selector, and will depend on the filtered_data. Note that it only uses the unique gear values found in the filtered data.
Then in our ui, we need to reference this dynamically created selector:
uiOutput("filter_gear")
This will behave like the other selector, but will update based on the carb filter.
Lastly, we can utilize this new filter like any other:
output$table <- renderPrint({
filtered_data() %>%
filter(gear %in% input$filter_gear) %>%
print()
})