Reputation: 59
I have 2 questions: 1) I would like to know if that is possible to make a column of selections depending on the previous input. Please see the code and I will explain what I mean:
library(shiny)
Country <- c("USA", "Mexico", "Canada", "China", "Vietnam", "India", "France", "Germany", "Poland")
Region <- c("Americas", "Americas", "Americas", "Asia", "Asia", "Asia", "Europe", "Europe", "Europe")
Product <- c(11, 22, 33, 44, 55, 66, 77, 88, 99)
Date <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
DF <- cbind(Region, Country, Product, Date)
DF <- as.data.frame(DF)
Region <- as.factor(sort(unique(DF$Region)))
Country <- as.factor(sort(unique(DF$Country)))
ui <- fluidPage(titlePanel("Filtering experiments"),
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(width = 3,
selectizeInput("RegionSelect", "Region", Region, selected = NULL, multiple = TRUE),
selectizeInput("CountrySelect", "Country", Country, selected = NULL, multiple = TRUE)),
# Main panel for displaying outputs ----
mainPanel( fluidPage( box(width = 12, tableOutput("table")) ) ) ) )server <- function(input, output) {
output$table <- renderTable({
filtered <- DF
if (!is.null(input$RegionSelect)) {filtered <- filtered %>% filter(Region == input$RegionSelect)}
if (!is.null(input$CountrySelect)) {filtered <- filtered %>% filter(Country == input$CountrySelect)}
Total <- data.frame(filtered$Product)
ShowTable <- data.frame(cbind(Total))
ShowTable
})}shinyApp(ui, server)
Whenever the Region is selected as "Americas" the user still see all of the countries, not only US, Canada and Mexico.
I tried to fix it by filtering like:
selectizeInput("CountrySelect", "Country", as.factor(sort(unique(filtered$Country %>% filter(Region == input$RegionSelect)}))), selected = NULL, multiple = TRUE))
But it did not work, so I hope you have some ideas.
2) Even if the " multiple = TRUE", whenever there are 2 or more inputs chosen in the same Input line the application stops working.
Thanks in advance!
Upvotes: 1
Views: 728
Reputation: 8506
You can use updateSelectizeInput
to update the content of selectizeInput
according to the value of another input.
Note that it is better to use observeEvent
than observe
statements (see here for details).
library(shiny)
library(dplyr)
Country <- c("USA", "Mexico", "Canada", "China", "Vietnam", "India", "France", "Germany", "Poland")
Region <- c("Americas", "Americas", "Americas", "Asia", "Asia", "Asia", "Europe", "Europe", "Europe")
Product <- c(11, 22, 33, 44, 55, 66, 77, 88, 99)
Date <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
DF <- cbind(Region, Country, Product, Date)
DF <- as.data.frame(DF)
Region <- as.factor(sort(unique(DF$Region)))
Country <- as.factor(sort(unique(DF$Country)))
ui <- fluidPage(titlePanel("Filtering experiments"),
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
width = 3,
selectizeInput(
"RegionSelect",
"Region",
Region,
selected = NULL,
multiple = TRUE
),
selectizeInput(
"CountrySelect",
"Country",
Country,
selected = NULL,
multiple = TRUE
)
),
# Main panel for displaying outputs ----
mainPanel(fluidPage(
width = 12, tableOutput("table")
))
))
server <- function(input, output, session) {
observeEvent(input$RegionSelect, {
req(input$RegionSelect)
test <- DF %>%
filter(Region %in% input$RegionSelect) %>%
select(Country)
updateSelectizeInput(session,
inputId = "CountrySelect",
choices = test)
})
output$table <- renderTable({
# Uncomment the two lines with comments if you want to make it mandatory to chose a continent to show the table
# req(input$RegionSelect)
req(input$CountrySelect)
DF %>%
# filter(Region %in% input$RegionSelect) %>%
filter(Country %in% input$CountrySelect)
})}
shinyApp(ui, server)
Upvotes: 1
Reputation: 2821
You can add an updateSelectInput
, like this:
observe({
region <- input$RegionSelect
req(region)
updateSelectInput(session, "CountrySelect",
choices = filter(DF, Region == !!region)$Country)
})
Also, please fix your (nearly) working example: you need a library(dplyr)
, and remove box
(since that is from shinydashboard
only, which you are not using).
Upvotes: 1