Следующее делает то, что вы хотите, без иерархии, но с использованием pickerInput
и условных операторов в операторе observeEvent
. Сначала он выглядит сложным, но делает то, что должен.
library(shiny)
library(dplyr)
library(plotly)
data("mtcars")
# create ui
ui <- fluidPage(fluidRow(
box(
title = "Filter",
pickerInput(
inputId = "cyl_pickerinput",
label = "CYL",
choices = levels(as.factor(mtcars$cyl)),
multiple = T,
selected = levels(as.factor(mtcars$cyl)),
options = list(
`live-search` = TRUE,
#`actions-box` = TRUE,
`selected-text-format` = "count",
`count-selected-text` = "{0} out of {1} cyl selected"
)
),
pickerInput(
inputId = "vs_pickerinput",
label = "VS",
choices = levels(as.factor(mtcars$vs)),
multiple = T,
selected = levels(as.factor(mtcars$vs)),
options = list(
`live-search` = TRUE,
#`actions-box` = TRUE,
`selected-text-format` = "count",
`count-selected-text` = "{0} out of {1} vs selected"
)
),
pickerInput(
inputId = "carb_pickerinput",
label = "CARB",
choices = levels(as.factor(mtcars$carb)),
multiple = T,
selected = levels(as.factor(mtcars$carb)),
options = list(
`live-search` = TRUE,
#`actions-box` = TRUE,
`selected-text-format` = "count",
`count-selected-text` = "{0} out of {1} carb selected"
)
),
),
box(title = "Plot of mtcars",
plotlyOutput("carplot"))
),)
# create server
server <- function(input, output, session) {
#(1) Create PickerInput Updates
observeEvent(
# define pickerinputs to be observed
c(
input$vs_pickerinput,
input$carb_pickerinput,
input$cyl_pickerinput
),
{
## filter the data based on the pickerinputs
# include an ifelse condition first to check wheter at least one value is choosen in all of the filters.
mtcars2 <-
if (!is.null(input$cyl_pickerinput) &
!is.null(input$vs_pickerinput) &
!is.null(input$carb_pickerinput)) {
mtcars %>%
filter(cyl %in% input$cyl_pickerinput) %>% # filters
filter(vs %in% input$vs_pickerinput) %>%
filter(carb %in% input$carb_pickerinput)
}
else{
mtcars
}
## update PickerInput based on a condition that requires the user to choose at least one input, else reset all filters
# for cyl
if (!is.null(input$cyl_pickerinput)) {
updatePickerInput(
session,
"cyl_pickerinput",
choices = levels(factor(mtcars$cyl)),
selected = unique(mtcars2$cyl))
} else{
}
# for carb
if (!is.null(input$carb_pickerinput)) {
updatePickerInput(
session,
"carb_pickerinput",
choices = levels(factor(mtcars$carb)),
selected = unique(mtcars2$carb)
)
}
# for vs
if (!is.null(input$vs_pickerinput)) {
updatePickerInput(
session,
"vs_pickerinput",
choices = levels(factor(mtcars$vs)),
selected = unique(mtcars2$vs)
)
}
},
ignoreInit = TRUE,
ignoreNULL = F
)
# (2) Create reactive object with filtered data
# update mtcars table based on filters
mtcars.reactive <-
reactive({
if (!is.null(input$vs_pickerinput))
# one condition should be enough.
{
mtcars %>% # filters
filter(
cyl %in% input$cyl_pickerinput &
vs %in% input$vs_pickerinput &
carb %in% input$carb_pickerinput
)
} else
{
mtcars
}
})
# (3) create the plot output
output$carplot <-
renderPlotly({
# create plot
plot <- ggplot(mtcars.reactive()) +
geom_point(aes(wt, mpg, color = factor(vs)))
# convert to plotly
ggplotly(plot)
})
}
shinyApp(ui, server)