Store dynamic R shiny inputs in dataframe - r

I want to have a UI which allows a user to give certain inputs, and if he requires more inputs he shall be able to click a button which then opens up new inputs. This has worked out fine thanks to this entry.
However, now I want to create a dataframe out of these inputs and I am struggling with that. This is my code:
library(shiny)
ui <- fluidPage(
fluidRow(
column(
width = 6,
uiOutput("selection_ui")
),
column(
width = 3,
uiOutput("amount_ui")
),
column(
width = 3,
uiOutput("year_ui")
)
),
fluidRow(
column(
width = 6,
actionButton(inputId = "addEntry",
label = "Add Entry")
),
column(
width = 6,
actionButton(inputId = "deleteEntry",
label = "Delete Entry")
)
),
br(),
fluidRow(
column(
width = 12,
actionButton(inputId = "Go",
label = "Submit")
)
),
dataTableOutput("Dataframe")
)
server <- function(input, output){
counter <- reactiveValues(value = 1)
AllInputs <- reactive({
x <- reactiveValuesToList(input)
})
observeEvent(input$addEntry, {
counter$value <- counter$value + 1
})
observeEvent(input$deleteEntry, {
req( counter$value >= 2 )
counter$value <- counter$value - 1
})
selection <- reactive({
n <- counter$value
if(n > 0){
isolate({
lapply(seq_len(n), function(i){
selectInput( inputId = paste0("select",i),
label = paste0(i, "-th selection:"),
choices = as.list(c("", "A", "B", "C")),
selected = AllInputs()[[paste0("select",i)]]
)
})
})
}
})
amount <- reactive({
n <- counter$value
if(n > 0){
isolate({
lapply(seq_len(n), function(i){
numericInput(inputId = paste0("number",i),
label = paste0(i, "-th amount:"),
value = AllInputs()[[paste0("number",i)]])
})
})
}
})
year <- reactive({
n <- counter$value
if(n > 0){
isolate({
lapply(seq_len(n), function(i){
numericInput(inputId = paste0("year",i),
label = paste0(i, "-th year:"),
value = AllInputs()[[paste0("year",i)]])
})
})
}
})
output$selection_ui <- renderUI({selection()})
output$amount_ui <- renderUI({amount()})
output$year_ui <- renderUI({year()})
eventReactive(input$Go, {
df <- data.frame(CREATE DATAFRAME HERE)
})
output$dataframe <- renderDataTable(df())
}
shinyApp(ui = ui, server = server)

I think I solved it using sapply():
df <- eventReactive(input$Go, {
n <- counter$value
tmp1 <- sapply(seq_len(n), function(i){
input[[paste0("select",i)]]
})
tmp2 <- sapply(seq_len(n), function(i){
input[[paste0("number",i)]]
})
tmp3 <- sapply(seq_len(n), function(i){
input[[paste0("year",i)]]
})
data.frame(col1 = tmp1,
col2 = tmp2,
col3 = tmp3
)
})

Related

Cannot use data in shiny after for loop

I'm trying to write a shiny app for pseudonymisation. It needs to receive a CSV file, let the user select which columns need to be removed, and download the data. The problem I cannot solve is why the for loop doesn't work as it does in a normal script.
Here is the code.
UI
library(shiny)
fluidPage(
titlePanel("Anonimizador"),
sidebarLayout(
sidebarPanel(
fileInput(
'file_input',
'Escolha a base de dados para anonimização',
accept = c(
'text/csv',
'text/comma-separated-values',
'.csv'
)
),
radioButtons(
"separador",
"Separador: ",
choices = c(";",",",":")
),
radioButtons(
"encoding",
"Encoding: ",
choices = c("UTF-8", "latin1")
)
),
mainPanel(
fluidRow(
dataTableOutput("table_output")
),
hr(),
fluidRow(
column(
6,
checkboxGroupInput(
"colunas",
"Selecione as colunas para anonimizar:",
choices = NULL
)
),
column(
6,
downloadButton(
'downloadData',
'Baixe a base anonimizada'
)
)
)
)
)
)
SERVER
library(shiny)
library(dplyr)
shinyServer(function(session, input, output) {
db <- reactive({
inFile <- input$file_input
if (is.null(inFile)) return(NULL)
db <- read.csv(
inFile$datapath,
header = TRUE,
sep = input$separador,
encoding = input$encoding
)
return(db)
})
output$table_output <- renderDataTable({
db <- db()
db
},
options = list(
scrollX = TRUE,
pageLength = 5
)
)
observe({
updateCheckboxGroupInput(
session,
"colunas",
"Selecione as colunas para anonimizar:",
choices = names(db())
)
})
db_anonimizado <- reactive({
db <- db()
colunas <- names(db[,input$colunas])
db_novo <- db
for (i in 1:length(colunas)) {
unicos <- data.frame(
original = unique(db[,colunas[i]]),
novo = 1:nrow(unique(db[,colunas[i]]))
)
db_novo <- left_join(db_novo, unicos, by = colunas[i])
}
db_novo$unico <- 1:nrow(db_novo)
nomes_novos <- names(db_novo[,(ncol(db_novo)-length(colunas)): ncol(db_novo)])
db_novo$indicador_anonimizado <- do.call(
paste0,
db_novo[,nomes_novos]
)
remove <- c(colunas, nomes_novos)
db_novo <- db_novo[,-which(names(db_novo) %in% remove)]
db_novo
})
output$downloadData <- downloadHandler(
filename = function() {
paste('anonimizada.csv')
},
content = function(file) {
write.csv(
db_anonimizado(),
file
)
}
)
})
If anyone could help me I'd be very grateful
You have several issues in your code.
When you select only one column, you need to handle it slightly differently in the for loop.
nrow(unique(db[,colunas[i]])) gives a NULL for me. Perhaps length() is better here.
You needed a +1 in ncol(db_novo)-length(colunas)+1
Full code
library(shiny)
ui <- fluidPage(
titlePanel("Anonimizador"),
sidebarLayout(
sidebarPanel(
fileInput(
'file_input',
'Escolha a base de dados para anonimização',
accept = c(
'text/csv',
'text/comma-separated-values',
'.csv'
)
),
radioButtons(
"separador",
"Separador: ",
choices = c(",",";",":")
),
radioButtons(
"encoding",
"Encoding: ",
choices = c("UTF-8", "latin1")
)
),
mainPanel(
fluidRow(
dataTableOutput("table_output"), DTOutput("t1")
),
hr(),
fluidRow(
column(
6,
checkboxGroupInput(
"colunas",
"Selecione as colunas para anonimizar:",
choices = NULL
)
),
column(
6,
downloadButton(
'downloadData',
'Baixe a base anonimizada'
)
)
)
)
)
)
library(dplyr)
server <- shinyServer(function(session, input, output) {
db <- reactive({
inFile <- input$file_input
if (is.null(inFile)) return(NULL)
db <- read.csv(
inFile$datapath,
header = TRUE,
sep = input$separador,
encoding = input$encoding
)
return(db)
})
output$table_output <- renderDataTable({
db <- db()
db
},
options = list(
scrollX = TRUE,
pageLength = 5
)
)
observe({
updateCheckboxGroupInput(
session,
"colunas",
"Selecione as colunas para anonimizar:",
choices = names(db())
)
})
db_anonimizado <- reactive({
req(input$colunas,db())
db <- db()
colunas <- names(db[,input$colunas])
db_novo <- db
n <- length(input$colunas)
if (n==1) {
unicos <- data.frame(
original = unique(db[,input$colunas]),
novo1 = 1:length(unique(db[,input$colunas]))
)
names(unicos)[1] <- c(sym(input$colunas))
db_novo <- left_join(db_novo, unicos, by = names(unicos)[1])
lastcol <- ncol(db_novo)
nomes_novos <- c(names(db_novo)[lastcol])
remove <- c(input$colunas, nomes_novos)
db_novo$indicador_anonimizado <- db_novo[,c(nomes_novos)]
}else if (n>1) {
for (i in 1:n) {
unicos <- data.frame(
original = unique(db[,colunas[i]]),
novo2 = 1:length(unique(db[,colunas[i]]))
)
names(unicos)[1] <- c(sym(colunas[i]))
db_novo <- left_join(db_novo, unicos, by = colunas[i])
}
nomes_novos <- names(db_novo[,(ncol(db_novo)-length(colunas)+1): ncol(db_novo)])
remove <- c(colunas, nomes_novos)
db_novo$indicador_anonimizado <- do.call(
paste0,
db_novo[,c(nomes_novos)]
)
}
#print(nomes_novos)
db_novo$unico <- 1:nrow(db_novo)
#nomes_novos <- names(db_novo[,(ncol(db_novo)-length(colunas)): ncol(db_novo)])
# db_novo$indicador_anonimizado <- do.call(
# paste0,
# db_novo[,c(nomes_novos)]
# )
#remove <- c(colunas, nomes_novos)
db_novo <- db_novo[,-which(names(db_novo) %in% remove)]
db_novo
})
output$t1 <- renderDT({
req(db_anonimizado())
db_anonimizado()
})
output$downloadData <- downloadHandler(
filename = function() {
paste('anonimizada.csv')
},
content = function(file) {
write.csv(
db_anonimizado(),
file
)
}
)
})
shinyApp(ui, server)

Shiny Modules: Handling a list of buttons

I am trying to build an app that relies on a list of buttons created via lapply. I can successfully reference the buttons using observeEvent when I am not working with modularized code. However, when I try to use modules, the observeEvent doesn't work. I suspect it has something to do with how Shiny handles the namespace id's, but despite a couple of days of experimentation, I have not been able to solve the issue.
Below I will post first the non-modularized dummy app that does work (stolen from this other stack overflow question: R Shiny: How to write loop for observeEvent). Then I will share my existing modularized code that does not work.
Working non-modularized code:
library("shiny")
ui <- fluidPage(
fluidRow(
column(
width = 6,
lapply(
X = 1:6,
FUN = function(i) {
sliderInput(inputId = paste0("d", i), label = i, min = 0, max = 10, value = i)
}
)
),
column(
width = 6,
verbatimTextOutput(outputId = "test")
)
)
)
server <- function(input, output){
vals <- reactiveValues()
lapply(
X = 1:6,
FUN = function(i){
observeEvent(input[[paste0("d", i)]], {
vals[[paste0("slider", i)]] <- input[[paste0("d", i)]]
})
}
)
output$test <- renderPrint({
reactiveValuesToList(vals)
})
}
shinyApp(ui = ui, server = server)
Modularized Code that fails:
library(shiny)
slidersUI <- function(id){
ns <- NS(id)
tagList(
fluidRow(
column(
width = 6,
lapply(
X = 1:6,
FUN = function(i) {
sliderInput(inputId = paste0("d", i), label = i, min = 0, max = 10, value = i)
} ),
column(
width = 6,
verbatimTextOutput(outputId = "test")
)
)))
}
slidersServer <- function(input, output, session){
vals <- reactiveValues()
lapply(
X = 1:6,
FUN = function(i){
output$test2 <- renderText(paste0("this is i:", i))
observeEvent(input[[paste0("d", i)]], {
vals[[paste0("slider", i)]] <- input[[paste0("d", i)]]
})
}
)
output$test <- renderPrint({
reactiveValuesToList(vals)
})
}
library("shiny")
ui <- fluidPage(
slidersUI("TheID")
)
server <- function(input, output){
callModule(slidersServer, "TheID")
}
shinyApp(ui = ui, server = server)
Thank you!
You need to wrap your IDs in ns to get the correct namespace. Here is the corrected module ui:
slidersUI <- function(id){
ns <- NS(id)
tagList(
fluidRow(
column(
width = 6,
lapply(
X = 1:6,
FUN = function(i) {
sliderInput(inputId = ns(paste0("d", i)), label = i, min = 0, max = 10, value = i)
} ),
column(
width = 6,
verbatimTextOutput(outputId = ns("test"))
)
)))
}

shiny dynamically add input fields and data without getting re-rendered

I'm trying to dynamically add new variables to my shiny app which is working but if I start editing one, the values (text and numeric) reset each time I then add an additional variable. This example works without needing a for loop using reactiveValuesToList() but when I apply it to my code, it doesn't work. Here is my working example:
library(shiny)
dist <- c("Normal", "Gamma")
ui <- shinyUI(fluidPage(
sidebarPanel(
actionButton("add_btn", "Add Textbox"),
actionButton("rm_btn", "Remove Textbox"),
textOutput("counter")
),
mainPanel(uiOutput("textbox_ui"))
))
server <- shinyServer(function(input, output, session) {
# Track the number of input boxes to render
counter <- reactiveValues(n = 0)
# Track all user inputs
AllInputs <- reactive({
x <- reactiveValuesToList(input)
})
observeEvent(input$add_btn, {counter$n <- counter$n + 1})
observeEvent(input$rm_btn, {
if (counter$n > 0) counter$n <- counter$n - 1
})
output$counter <- renderPrint(print(counter$n))
textboxes <- reactive({
n <- counter$n
if (n > 0) {
isolate({
lapply(seq_len(n), function(i) {
fluidRow(
selectInput(inputId = paste0("news", i),
label = paste0("Variable ", i),
choices = dist),
conditionalPanel(
condition = sprintf("input.%s=='Normal'", paste0("news", i)),
textInput("txt", "Text input:", paste0("var", i)),
column(width = 3, numericInput('normal_mean', 'Mean', value = '0')), column(width = 3, numericInput('normal_sd', 'Standard deviation', value = '1'))),
conditionalPanel(
condition = sprintf("input.%s=='Gamma'", paste0("news", i)),
textInput("txt", "Text input:", paste0("var", i)),
column(width = 3, numericInput('gamma_shape', 'Shape', value = '0')), column(width = 3, numericInput('gamma_scale', 'Scale', value = '1')))
)
})
})
}
})
output$textbox_ui <- renderUI({ textboxes() })
})
shinyApp(ui, server)
Now if I try and add AllInputs()[[]] to textInput it doesn't keep the text in the conditionalPanel call:
conditionalPanel(
condition = sprintf("input.%s=='Normal'", paste0("news", i)),
textInput("txt", "Text input:", AllInputs()[[paste0("var", i)]]),
column(width = 3, numericInput('normal_mean', 'Mean', value = '0')), column(width = 3, numericInput('normal_sd', 'Standard deviation', value = '1')))
I'm also not sure how to include AllInputs()[[]] to the numeric values so that they dont change.
I think the problem is because of my condition line within conditionalPanel but can't figure it out, any suggestions? thanks
You should consider using modules and insertUI / removeUI. Clicking on the buttons will not reset your changes on the inputs you already called. Here, you just have inputs so you only need to call the function add_box I created, but if you want to add outputs in the module, then you will need to use the function callModule in observeEvent. This is explained in the article I refer to.
This is not the method you suggested but it works.
library(shiny)
dist <- c("Normal", "Gamma")
add_box <- function(id){
ns <- NS(id)
tags$div(id = paste0("new_box", id),
selectInput(inputId = ns("news"),
label = paste0("Variable ", id),
choices = dist),
conditionalPanel(
condition = "input.news=='Normal'",
ns = ns,
textInput(ns("txt"), "Text input:", paste0("var", id)),
column(width = 3, numericInput(ns('normal_mean'), 'Mean', value = '0')),
column(width = 3, numericInput(ns('normal_sd'), 'Standard deviation', value = '1'))),
conditionalPanel(
condition = "input.news=='Gamma'",
ns = ns,
textInput(ns("txt"), "Text input:", paste0("var", id)),
column(width = 3, numericInput(ns('gamma_shape'), 'Shape', value = '0')),
column(width = 3, numericInput(ns('gamma_scale'), 'Scale', value = '1')))
)
}
ui <- shinyUI(fluidPage(
sidebarPanel(
actionButton("add_btn", "Add Textbox"),
actionButton("rm_btn", "Remove Textbox"),
textOutput("counter")
),
mainPanel(column(width = 12, id = "column"))
))
server <- shinyServer(function(input, output, session) {
# Track the number of input boxes to render
counter <- reactiveValues(n = 0)
# Track all user inputs
AllInputs <- reactive({
x <- reactiveValuesToList(input)
})
observeEvent(input$add_btn, {
counter$n <- counter$n + 1
insertUI(selector = "#column",
where = "beforeEnd",
ui = add_box(counter$n)
)
})
observeEvent(input$rm_btn, {
if (counter$n > 0) {
removeUI(selector = paste0("#new_box", counter$n))
counter$n <- counter$n - 1
}
})
output$counter <- renderPrint(print(counter$n))
})
shinyApp(ui, server)

Selection of columns for the table in Shiny

I would like to add a new category at the beginning which will select the columns for the table. I can not combine variables with other elements in an application. Could someone explain to me what I'm doing wrong? As you can see on the graphics program does not work well.
My code:
library(shiny)
data <- data.frame(
Category1 = rep(letters[1:3], each = 15),
Info = paste("Text info", 1:45),
Category2 = sample(letters[15:20], 45, replace = T),
Size = sample(1:100, 45),
MoreStuff = paste("More Stuff", 1:45)
)
ui <- fluidPage(titlePanel("Test Explorer"),
sidebarLayout(
sidebarPanel(
selectizeInput(
"show_vars",
"Columns to show:",
choices = colnames(data),
multiple = TRUE,
selected = c("Category1", "Info", "Category2")
),
uiOutput("category1"),
uiOutput("category2"),
uiOutput("sizeslider")
),
mainPanel(tableOutput("table"))
))
server <- function(input, output, session) {
data2 <- reactive({
req(input$table)
if (input$table == "All") {
return(data)
}
data[, names(data) %in% input$show_vars]
})
output$category1 <- renderUI({
selectizeInput('cat1',
'Choose Cat 1',
choices = c("All", sort(as.character(
unique(data$Category1)
))),
selected = "All")
})
df_subset <- eventReactive(input$cat1, {
if (input$cat1 == "All") {
df_subset <- data
}
else{
df_subset <- data[data$Category1 == input$cat1, ]
}
})
df_subset1 <- reactive({
if (is.null(input$cat2)) {
df_subset()
} else {
df_subset()[df_subset()$Category2 %in% input$cat2, ]
}
})
output$category2 <- renderUI({
selectizeInput(
'cat2',
'Choose Cat 2 (optional):',
choices = sort(as.character(unique(
df_subset()$Category2
))),
multiple = TRUE,
options = NULL
)
})
output$sizeslider <- renderUI({
sliderInput(
"size",
label = "Size Range",
min = min(df_subset1()$Size),
max = max(df_subset1()$Size),
value = c(min(df_subset1()$Size), max(df_subset1()$Size))
)
})
df_subset2 <- reactive({
if (is.null(input$size)) {
df_subset1()
} else {
df_subset1()[df_subset1()$Size >= input$size[1] &
df_subset1()$Size <= input$size[2], ]
}
})
output$table <- renderTable({
df_subset2()
})
}
shinyApp(ui, server)
You have few problems with your code
You stored that reactive value of the columns selection in data2(), and displaying table df_subset2(). As with your code, the columns change when you add columns and select Cat1 dropdown, since its values are dependent on the data.react.
Avoid using generic names like data to store data. Sometimes it interfere with R base names
You need to use ObserveEvent and eventReactive, when you expect the change on UI to reflect
Below is what I fixed, you can change accordingly.
Added a submit button
Wrapped the input selections code into an ObserveEvent
By this, your data is displayed only when you click the submit button.
Here is the code.
library(shiny)
data.input <- data.frame(
Category1 = rep(letters[1:3], each = 15),
Info = paste("Text info", 1:45),
Category2 = sample(letters[15:20], 45, replace = T),
Size = sample(1:100, 45),
MoreStuff = paste("More Stuff", 1:45)
)
ui.r
ui <- fluidPage(titlePanel("Test Explorer"),
sidebarLayout(
sidebarPanel(
selectizeInput(
"show_vars",
"Columns to show:",
choices = colnames(data.input),
multiple = TRUE,
selected = c("Category1", "Info", "Category2")
),
actionButton("button", "An action button"),
uiOutput("category1"),
uiOutput("category2"),
uiOutput("sizeslider")
),
mainPanel(tableOutput("table"))
))
server.r
server <- function(input, output, session) {
data.react <- eventReactive(input$button, {
data.input[, input$show_vars]
})
observeEvent(input$button, {
output$category1 <- renderUI({
data.sel <- data.react()
selectizeInput('cat1',
'Choose Cat 1',
choices = c("All", sort(as.character(
unique(data.sel$Category1)
))),
selected = "All")
})
df_subset <- eventReactive(input$cat1, {
data.sel <- data.react()
if (input$cat1 == "All") {
data.sel
}
else{
data.sel[data.sel$Category1 == input$cat1,]
}
})
output$category2 <- renderUI({
selectizeInput(
'cat2',
'Choose Cat 2 (optional):',
choices = sort(as.character(unique(
df_subset()$Category2
))),
multiple = TRUE,
options = NULL
)
})
df_subset1 <- reactive({
if (is.null(input$cat2)) {
df_subset()
} else {
df_subset()[df_subset()$Category2 %in% input$cat2,]
}
})
output$sizeslider <- renderUI({
sliderInput(
"size",
label = "Size Range",
min = min(data.input$Size),
max = max(data.input$Size),
value = c(min(data.input$Size), max(data.input$Size))
)
})
df_subset2 <- reactive({
if (is.null(input$size)) {
df_subset1()
} else {
df_subset1()[data.input$Size >= input$size[1] &
data.input$Size <= input$size[2],]
}
})
output$table <- renderTable({
df_subset2()
})
})
}
shinyApp(ui, server)

Shiny: select variables to table

I have one question to open the topic already. Well, I'm trying to do a similar app to this one Shiny: dynamic dataframe construction; renderUI, observe, reactiveValues. And I would like to add a new category at the beginning which will select the variables from the table. I can not combine variables with other elements in an application. Could someone explain to me what I'm doing wrong?
As you can see on the graphics program does not work well.
Below is a script
#rm(list = ls())
library(shiny)
data <- data.frame(Category1 = rep(letters[1:3],each=15),
Info = paste("Text info",1:45),
Category2 = sample(letters[15:20],45,replace=T),
Size = sample(1:100, 45),
MoreStuff = paste("More Stuff",1:45))
ui <- fluidPage(
titlePanel("Test Explorer"),
sidebarLayout(
sidebarPanel(
selectizeInput("show_vars", "Columns to show:",
choices = colnames(data), multiple = TRUE,
selected = c("Category1","Info","Category2")),
uiOutput("category1"),
uiOutput("category2"),
uiOutput("sizeslider")
),
mainPanel(
tableOutput("table")
)
)
)
server <- function(input, output,session) {
data2 <- reactive({
req(input$table)
if(input$table == "All"){
return(data)
}
data[,names(data) %in% input$show_vars]
})
output$category1 <- renderUI({
selectizeInput('cat1', 'Choose Cat 1', choices = c("All",sort(as.character(unique(data$Category1)))),selected = "All")
})
df_subset <- eventReactive(input$cat1,{
if(input$cat1=="All") {df_subset <- data}
else{df_subset <- data[data$Category1 == input$cat1,]}
})
df_subset1 <- reactive({
if(is.null(input$cat2)){df_subset()} else {df_subset()[df_subset()$Category2 %in% input$cat2,]}
})
output$category2 <- renderUI({
selectizeInput('cat2', 'Choose Cat 2 (optional):', choices = sort(as.character(unique(df_subset()$Category2))), multiple = TRUE,options=NULL)
})
output$sizeslider <- renderUI({
sliderInput("size", label = "Size Range", min=min(df_subset1()$Size), max=max(df_subset1()$Size), value = c(min(df_subset1()$Size),max(df_subset1()$Size)))
})
df_subset2 <- reactive({
if(is.null(input$size)){df_subset1()} else {df_subset1()[df_subset1()$Size >= input$size[1] & df_subset1()$Size <= input$size[2],]}
})
output$table <- renderTable({
df_subset2()
})
}
shinyApp(ui, server)
You don't need data2 since you are not using it and instead you can just use the same condition to filter columns with %in% everywhere you are displaying the dataframe.
#rm(list = ls())
library(shiny)
data <- data.frame(Category1 = rep(letters[1:3],each=15),
Info = paste("Text info",1:45),
Category2 = sample(letters[15:20],45,replace=T),
Size = sample(1:100, 45),
MoreStuff = paste("More Stuff",1:45))
ui <- fluidPage(
titlePanel("Test Explorer"),
sidebarLayout(
sidebarPanel(
selectizeInput("show_vars", "Columns to show:",
choices = colnames(data), multiple = TRUE,
selected = c("Category1","Info","Category2")),
uiOutput("category1"),
uiOutput("category2"),
uiOutput("sizeslider")
),
mainPanel(
tableOutput("table")
)
)
)
server <- function(input, output,session) {
output$category1 <- renderUI({
selectizeInput('cat1', 'Choose Cat 1', choices = c("All",sort(as.character(unique(data$Category1)))),selected = "All")
})
df_subset <- eventReactive(input$cat1,{
if(input$cat1=="All") {df_subset <- data}
else{df_subset <- data[data$Category1 == input$cat1,names(data) %in% input$show_vars]}
})
df_subset1 <- reactive({
if(is.null(input$cat2)){df_subset()} else {df_subset()[df_subset()$Category2 %in% input$cat2,names(data) %in% input$show_vars]}
})
output$category2 <- renderUI({
selectizeInput('cat2', 'Choose Cat 2 (optional):', choices = sort(as.character(unique(df_subset()$Category2))), multiple = TRUE,options=NULL)
})
output$sizeslider <- renderUI({
sliderInput("size", label = "Size Range", min=min(df_subset1()$Size), max=max(df_subset1()$Size), value = c(min(df_subset1()$Size),max(df_subset1()$Size)))
})
df_subset2 <- reactive({
if(is.null(input$size)){df_subset1()} else {df_subset1()[df_subset1()$Size >= input$size[1] & df_subset1()$Size <= input$size[2],names(data) %in% input$show_vars]}
})
output$table <- renderTable({
df_subset2()
})
}
shinyApp(ui, server)

Resources