I would like to allow multiple selection in my shiny app, and display the filtered dataset.
The code is as below:
library(shiny)
library(ggplot2)
library(dplyr)
result_table = mtcars
fluidPage(
tabsetPanel(
tabPanel("Import data",
titlePanel("Test"),
# Create a new Row in the UI for selectInputs
fluidRow(
column(4,
selectInput("cyl",
"cyl:",
c("All",
unique(as.character(result_table$cyl)))
)
),
column(4,
selectInput("vs",
"vs:",
c("All",
unique(as.character(result_table$vs))),
multiple = T)
),
),
# Create a new row for the table.
DT::dataTableOutput("table")
),
tabPanel("test2",
titlePanel("test"),
# Create a new Row in the UI for selectInputs
fluidRow(
column(4,
selectInput("cyl",
"cyl:",
c("All",
unique(as.character(result_table$cyl)))
)
),
column(4,
selectInput("vs",
"vs:",
c("All",
unique(as.character(result_table$vs))),
multiple = T)
),
)
)
)
)
# Load the ggplot2 package which provides
# the 'mpg' dataset.
library(ggplot2)
function(input, output) {
# Filter data based on selections
output$table <- DT::renderDataTable(DT::datatable({
data <- result_table
if (input$cyl!= "All") {
data <- data[data$cyl== input$cyl,]
}
if (!(input$vs%in% "All")) {
data <- data[(data$vs%in% input$vs),]
}
data
}))
}
When I run the code, the following error popped up:
I suspected that the error appeared because of if
function in the server side…But I cannot figure out the reason. Maybe the format of input
is not the same as data
?
Please give me some suggestions. Thank you.
>Solution :
There are two issues with your code. First, when using multiple=TRUE
the selected=
argument defaults to no value. That’s why you an error as input$vs
is NULL
when you start your app. To prevent that set a selected
value or account for the case of a NULL
value in your server. Second, all input id
s have to be unique, whereas you used the same id
s for the selectInput
s in both tabPanel
s. Hence, I renamed them to XXX2
.
library(shiny)
result_table <- mtcars
ui <- fluidPage(
tabsetPanel(
tabPanel(
"Import data",
titlePanel("Test"),
# Create a new Row in the UI for selectInputs
fluidRow(
column(
4,
selectInput(
"cyl",
"cyl:",
c(
"All",
unique(as.character(result_table$cyl))
)
)
),
column(
4,
selectInput("vs",
"vs:",
c(
"All",
unique(as.character(result_table$vs))
),
selected = "All",
multiple = TRUE
)
),
),
# Create a new row for the table.
DT::dataTableOutput("table")
),
tabPanel(
"test2",
titlePanel("test"),
fluidRow(
column(
4,
selectInput(
"cyl2",
"cyl:",
c(
"All",
unique(as.character(result_table$cyl))
)
)
),
column(
4,
selectInput("vs2",
"vs:",
c(
"All",
unique(as.character(result_table$vs))
),
selected = "All",
multiple = TRUE
)
),
)
)
)
)
server <- function(input, output) {
# Filter data based on selections
output$table <- DT::renderDataTable(DT::datatable({
data <- result_table
if (input$cyl != "All") {
data <- data[data$cyl == input$cyl, ]
}
if (!(input$vs %in% "All")) {
data <- data[data$vs %in% input$vs, ]
}
data
}))
}
shinyApp(ui, server)
#>
#> Listening on http://127.0.0.1:8331