I have the following code below that allows for three different "phases" of selection, each input dependent on the one before. Right now the code exists like this:
ui <- fluidPage(
titlePanel("Test Dashboard "),
sidebarLayout(
sidebarPanel(
uiOutput("data1"), ## uiOutput - gets the UI from the server
uiOutput("data2"),
uiOutput("data3")
),
mainPanel()
))
server <- function(input, output){
State <- c("NV", "NV","NV", "MD", "MD", "MD", "MD", "NY", "NY", "NY", "OH", "OH", "OH")
County <- c("CLARK", "WASHOE", "EUREKA", "MONTGOMERY", "HOWARD", "BALTIMORE", "FREDERICK", "BRONX", "QUEENS", "WESTCHESTER", "FRANKLIN", "SUMMIT", "STARK" )
City <- c("Las Vegas", "Reno", "Eureka", "Rockville", "Columbia", "Baltimore", "Thurmont", "Bronx", "Queens", "Yonkers", "Columbus", "Akron", "Canton")
Rating<- c(1,2,3,4,5,6,7,8,9,10,11,12,13)
df <- data.frame(State, County, City, Rating, stringsAsFactors = F)
## renderUI - renders a UI element on the server
## used when the UI element is dynamic/dependant on data
output$data1 <- renderUI({
selectInput("data1", "Select State", choices = c(df$State))
})
## input dependant on the choices in `data1`
output$data2 <- renderUI({
selectInput("data2", "Select County", choices = c(df$County[df$State == input$data1]))
})
output$data3 <- renderUI({
selectInput("data3", "select City", choices = c(df$City[df$County == input$data2]))
})
}
shinyApp(ui, server)
You will notice the sample data is found in the server
side code and binded together to form df
.
But what if I didn't want to narrow my choice for each selection? Instead let's say I wanted to follow the following selection path: State = "MD", County = ALL, and City = ALL. While I would have the selection to choose just one or multiple selections, it would also include the selection to choose ALL.
Additionally, I would like to also include a dynamic table that is visible and adjusts itself based on the values selected. So if I were following the same selection path as listed above, it would return all the affiliated results for anything filed under State = "MD".
Whenever I try adding something like
DTOutput('table')
On the UI side and the following on the server side:
output$table <- renderDT(df,
options = list(
pageLength = 5
)
)
It just messes up the whole layout and also doesn't produce the table I need.
Here is something to try out. You can use updateSelectInput
to change your inputs and make them dependent. A separate reactive
expression can filter your data based on your inputs. See if this gives you the intended behavior.
library(shiny)
library(DT)
State <- c("NV", "NV","NV", "MD", "MD", "MD", "MD", "NY", "NY", "NY", "OH", "OH", "OH")
County <- c("CLARK", "WASHOE", "EUREKA", "MONTGOMERY", "HOWARD", "BALTIMORE", "FREDERICK", "BRONX", "QUEENS", "WESTCHESTER", "FRANKLIN", "SUMMIT", "STARK" )
City <- c("Las Vegas", "Reno", "Eureka", "Rockville", "Columbia", "Baltimore", "Thurmont", "Bronx", "Queens", "Yonkers", "Columbus", "Akron", "Canton")
Rating<- c(1,2,3,4,5,6,7,8,9,10,11,12,13)
df <- data.frame(State, County, City, Rating, stringsAsFactors = F)
ui <- fluidPage(
titlePanel("Test Dashboard "),
sidebarLayout(
sidebarPanel(
selectInput("data1", "Select State", choices = c("All", unique(df$State))),
selectInput("data2", "Select County", choices = NULL),
selectInput("data3", "select City", choices = NULL)
),
mainPanel(
DTOutput("table")
)
))
server <- function(input, output, session){
observeEvent(input$data1, {
if (input$data1 != "All") {
updateSelectInput(session, "data2", "Select County", choices = c("All", unique(df$County[df$State == input$data1])))
} else {
updateSelectInput(session, "data2", "Select County", choices = c("All", unique(df$County)))
}
}, priority = 2)
observeEvent(c(input$data1, input$data2), {
if (input$data2 != "All") {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City[df$County == input$data2])))
} else {
if (input$data1 != "All") {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City[df$State == input$data1])))
} else {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City)))
}
}
}, priority = 1)
filtered_data <- reactive({
temp_data <- df
if (input$data1 != "All") {
temp_data <- temp_data[temp_data$State == input$data1, ]
}
if (input$data2 != "All") {
temp_data <- temp_data[temp_data$County == input$data2, ]
}
if (input$data3 != "All") {
temp_data <- temp_data[temp_data$City == input$data3, ]
}
temp_data
})
output$table <- renderDT(
filtered_data()
)
}
shinyApp(ui, server)