I am trying to generate a shiny app that will first allow the user to (using the notion of dplyr verbs) select the variables they are interested in and then filter those variables based on subsequent selections. I am trying to do this using conditionalPanel()
but I am getting stuck finding a way to access the input$
from each conditional panel.
Here is an example:
library('shiny')
library('tidyverse')
library('shinyWidgets')
#Create the data
data <- select(mtcars, c(gear, carb))
#Create page with sidebarlayout
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
#Create picker input where relevant variables are selected
pickerInput(
inputId = 'vars',
label = 'Variables',
choices = colnames(data),
selected = colnames(data),
multiple = T,
pickerOptions(actionsBox = TRUE)
),
#Create conditional panels which show when the variable above is selected
#These panels will be used to filter the data that is selected based on the above variables
conditionalPanel(condition = "input.vars.includes('gear')",
pickerInput(inputId = 'gear',
label = 'Gear',
choices = unique(data$gear),
selected = unique(data$gear),
multiple = T,
pickerOptions(actionsBox = TRUE)
)
),
conditionalPanel(condition = "input.vars.includes('carb')",
pickerInput(inputId = 'carb',
label = 'Carb',
choices = unique(data$carb),
selected = unique(data$carb),
multiple = T,
pickerOptions(actionsBox = TRUE)
)
)
),
mainPanel(
#Show the selected data
verbatimTextOutput('term_selected'),
#Show the selected and filtered data - this won't show
verbatimTextOutput('term_selected_filtered'),
#Try debug with just getting the
verbatimTextOutput('debug_print')
)
)
)
server <- function(input, output) {
#Create the reactive selected data
selected_data <- reactive ({
data %>%
select(input$vars)
})
#Render the selected data
output$term_selected <- renderPrint(selected_data())
#This is where i am stuck
#I need to find a way to access the inputs related to the conditional functions
# selected_filtered_data <- reactive ({
# for (i in length(input$vars)) {
# selected_data() %>%
# filter(input$[first condiitonal panel select] %in% as.symbol(input$vars[i])
# }
# })
#
output$term_selected_filtered <- renderPrint(selected_filtered_data())
#Try to render input input$[first item of input.vars]
output$debug_print <- renderPrint(input$as.symbol(input$vars[1]))
}
shinyApp(ui = ui, server = server)
The problem lies in the server. I have tried input$as.symbol(input$vars[1])
to access the input$gear
(assuming that was selected), but it just throws the error: attempt to apply non-function
. I tried adding !!
as syntactic sugar in front of as.symbol()
, but that makes no difference.
I also tried this, in the hope that i could conditionally filter, and had no luck.
selected_filtered_data <- reactive({
selected_data() %>%
if('gear' %in% input$vars) {
filter(gear %in% input$gear) %>%
}
if('carb' %in% input$vars) {
filter(carb %in% input$carb)
}
})
How should I go about doing this?
CodePudding user response:
We may use across
(if we want to filter
the rows when both column conditions are TRUE) or replace across
with if_any
(if either one of them is TRUE when they are both selected)
selected_data() %>%
filter(across(all_of(intersect(input$vars,
c('gear', "carb"))), ~ .x %in% input[[cur_column()]]))
-full code
library('shiny')
library('dplyr')
library(tidyr)
library('shinyWidgets')
#Create the data
data <- select(mtcars, c(gear, carb))
#Create page with sidebarlayout
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
#Create picker input where relevant variables are selected
pickerInput(
inputId = 'vars',
label = 'Variables',
choices = colnames(data),
selected = colnames(data),
multiple = TRUE,
pickerOptions(actionsBox = TRUE)
),
#Create conditional panels which show when the variable above is selected
#These panels will be used to filter the data that is selected based on the above variables
conditionalPanel(condition = "input.vars.includes('gear')",
pickerInput(inputId = 'gear',
label = 'Gear',
choices = unique(data$gear),
selected = unique(data$gear),
multiple = T,
pickerOptions(actionsBox = TRUE)
)
),
conditionalPanel(condition = "input.vars.includes('carb')",
pickerInput(inputId = 'carb',
label = 'Carb',
choices = unique(data$carb),
selected = unique(data$carb),
multiple = TRUE,
pickerOptions(actionsBox = TRUE)
)
)
),
mainPanel(
#Show the selected data
verbatimTextOutput('term_selected'),
#Show the selected and filtered data - this won't show
verbatimTextOutput('term_selected_filtered'),
#Try debug with just getting the
verbatimTextOutput('debug_print')
)
)
)
server <- function(input, output) {
#Create the reactive selected data
selected_data <- reactive ({
req(input$vars)
data %>%
select(input$vars)
})
#Render the selected data
output$term_selected <- renderPrint(selected_data())
#This is where i am stuck
#I need to find a way to access the inputs related to the conditional functions
selected_filtered_data <- reactive ({
selected_data() %>%
filter(across(all_of(intersect(input$vars, c('gear', "carb"))), ~ .x %in% input[[cur_column()]]))
})
#
output$term_selected_filtered <- renderPrint(
selected_filtered_data()
)
output$debug_print <- renderPrint(input[[input$vars[1]]])
}
shinyApp(ui = ui, server = server)
-output