I have a simple shiny app that loads a dataset when I launch it. The app has different selectizeInput()
where the user can choose one or more values of different variables with which he/she can filter the dataset. In the following reproducible example, the reactive dataset I create in the server when filtering is displayed through a table:
library(dplyr)
library(shiny)
dataset <- data.frame("Letters" = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C"),
"Numbers" = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9),
"LettersNumbers" = c("G5", "G5", "G5", "G5", "G5", "G5", "F7", "F7", "F7", "F7", "F7", "F7", "E9", "E9", "E9", "E9", "E9", "E9"))
ui <- fluidPage(
br(),
fluidRow(
column(width = 4,
selectizeInput(inputId = "letters",
label = "Letters",
choices = unique(dataset$Letters),
multiple = TRUE),
br(),
selectizeInput(inputId = "numbers",
label = "Numbers",
choices = unique(dataset$Numbers),
multiple = TRUE),
br(),
selectizeInput(inputId = "lettersnumbers",
label = "Letters & Numbers",
choices = unique(dataset$LettersNumbers),
multiple = TRUE)
),
column(width = 4,
tableOutput(outputId = "table")
),
column(width = 4,
textOutput(outputId = "text")
)
)
)
server <- function(input, output, session) {
# Filter the initial dataset
dataset_filtered <- reactive({
dataset_filtered <- dataset
if (!is.null(input$letters)) {
dataset_filtered <- dataset_filtered %>%
filter(Letters %in% c(input$letters))
}
if (!is.null(input$numbers)) {
dataset_filtered <- dataset_filtered %>%
filter(Numbers %in% c(input$numbers))
}
if (!is.null(input$lettersnumbers)) {
dataset_filtered <- dataset_filtered %>%
filter(LettersNumbers %in% c(input$lettersnumbers))
}
return(dataset_filtered)
})
# Display filtered table
output$table <- renderTable({
dataset_filtered()
})
# Display warning message
output$text <- renderText({
if (nrow(dataset_filtered()) == 0) {
print("No combinations available")
}
})
}
shinyApp(ui = ui, server = server)
The problem: The three variables have exactly the same importance. Let's now make an example of filtering: suppose I choose the values A and B. As you can see from the table, in the Numbers column I just have the values from 1 to 8, but not 9. Now, in the second selectizeInput()
(Numbers) I select the 9, and the table has, as expected 0 rows and the warning message is displayed.
However, if from the same selectizeInput()
I select both the 9 and the 1 some values will be displayed, because the filter considers the 1 as available in the reactive vector created and filters just for that.
In my opinion, the best way to program this interface is to reactively update every selectizeInput()
when a choice in any of them is made. In other words, if I select A and B from the first input, the number 9 should not be available in the second input AT ALL. This should be valid for every input I have, there is no input with more importance than the other.
I have tried several solutions, also with updateSelectizeInput()
, but nothing seems to work. Do you have any suggestion? Thanks!