R shiny observeEvent() cannot isolate the reactivity when input$files parameters changes - r

I met a problem abount R shiny observeEvent(). I have to upload three csv table files to separately show at different tabpanels. And I set a selectInput to set if to show header of table. At last I give a actionButton(ui)-observeEvent(server) to decide whether to run the showing process. But I find the selectInput just skip the observeEvent(), dynamicly change the show.That is observeEvent is invalidted.I dont'know why.I want selectInput can be under control of actionButton(). I doubt if observeEvent() is a good option to execute the job. Hope somebody can help me! Thanks in advance. Here is my demo code
# get 3 test uploaded files
data(mtcars)
test1 <- mtcars[,c(1:3)]
test2 <- mtcars[,c(5:8)]
test3 <- mtcars[c(1:3),]
write.csv(test1,file = "test1.csv")
write.csv(test2,file = "test2.csv")
write.csv(test3,file = "test3.csv")
# shiny part
library(shiny)
ui <- fluidPage(
# useShinyjs(),
sidebarLayout(
sidebarPanel(
fileInput(
inputId = "files",
label = "Choose CSV File",
multiple = TRUE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
tags$hr(),
selectInput("type", "Choose Data:", choices = c('Noheader'=TRUE,'Header'=FALSE)),
tags$hr(),
actionButton("update", "show",class = "btn btn-primary btn-lg",icon = icon("refresh"), width = "120px"),
),
mainPanel(
uiOutput("mytabs"),
textOutput("text_null", container = h4)
)
)
)
server <- function(input, output, session){
values <- reactiveValues(file_data=NULL)
filedata <- reactive({
req(input$files)
upload = list()
for(nr in 1:length(input$files[, 1])){
raw_name <- sub(".csv$", "",input$files[[nr, 'name']])
upload[[raw_name]] <- read.csv(file = input$files[[nr, 'datapath']],header = as.logical(input$type))
}
return((upload))
})
observe({
output$mytabs = renderUI({
values$file_data <- filedata()
nTabs <- length(filedata())
tabNames <- names(values$file_data)
myTabs = lapply(1: nTabs, function(i) {
tabPanel( tabNames[i],
tags$div(class = "group-output",
tags$br(),
tableOutput(paste0("Group",i))#))
)
)
})
do.call(tabsetPanel, myTabs)
})
})
observeEvent(input$update, {
values$file_data <- filedata()
nn_Tabs <- length(filedata())
progress <<- shiny::Progress$new()
on.exit(progress$close())
progress$set(message = "Begin to process data", value = 0)
for (i in 1: nn_Tabs){
local({
my_n <- i
TableName <- paste0("Group",my_n)
output[[TableName]] <- renderTable({ values$file_data[[my_n]] })
print(values$file_data[[my_n]])
progress$inc(1/nn_Tabs, detail = ", Please wait...")
})
}
progress$set(message = "Finished!", value = 1)
})
}
shinyApp(ui, server)

The problem is that you wrap output$mytabs in an observe. I'm not sure why this influences also the content of the output$Group1 etc. you generate in the renderUI call and overrules the observeEvent. Anyway, you don't need the observe, outputs are automatically updated when a dependency changes:
# get 3 test uploaded files
data(mtcars)
test1 <- mtcars[,c(1:3)]
test2 <- mtcars[,c(5:8)]
test3 <- mtcars[c(1:3),]
write.csv(test1,file = "test1.csv")
write.csv(test2,file = "test2.csv")
write.csv(test3,file = "test3.csv")
# shiny part
library(shiny)
ui <- fluidPage(
# useShinyjs(),
sidebarLayout(
sidebarPanel(
fileInput(
inputId = "files",
label = "Choose CSV File",
multiple = TRUE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
tags$hr(),
selectInput("type", "Choose Data:", choices = c('Noheader'=TRUE,'Header'=FALSE)),
tags$hr(),
actionButton("update", "show",class = "btn btn-primary btn-lg",icon = icon("refresh"), width = "120px"),
),
mainPanel(
uiOutput("mytabs"),
textOutput("text_null", container = h4)
)
)
)
server <- function(input, output, session){
values <- reactiveValues(file_data=NULL)
filedata <- reactive({
req(input$files)
upload = list()
for(nr in 1:length(input$files[, 1])){
raw_name <- sub(".csv$", "",input$files[[nr, 'name']])
upload[[raw_name]] <- read.csv(file = input$files[[nr, 'datapath']],header = as.logical(input$type))
}
return((upload))
})
output$mytabs = renderUI({
values$file_data <- filedata()
nTabs <- length(filedata())
tabNames <- names(values$file_data)
myTabs = lapply(1: nTabs, function(i) {
tabPanel( tabNames[i],
tags$div(class = "group-output",
tags$br(),
tableOutput(paste0("Group",i))#))
)
)
})
do.call(tabsetPanel, myTabs)
})
observeEvent(input$update, {
values$file_data <- filedata()
nn_Tabs <- length(filedata())
progress <<- shiny::Progress$new()
on.exit(progress$close())
progress$set(message = "Begin to process data", value = 0)
for (i in 1: nn_Tabs){
local({
my_n <- i
TableName <- paste0("Group",my_n)
output[[TableName]] <- renderTable({ values$file_data[[my_n]] })
print(values$file_data[[my_n]])
progress$inc(1/nn_Tabs, detail = ", Please wait...")
})
}
progress$set(message = "Finished!", value = 1)
})
}
shinyApp(ui, server)
Edit
I think this solution is more what you want. Maybe one can optimise the last observe statement to a better coding pattern:
# get 3 test uploaded files
data(mtcars)
test1 <- mtcars[,c(1:3)]
test2 <- mtcars[,c(5:8)]
test3 <- mtcars[c(1:3),]
write.csv(test1,file = "test1.csv")
write.csv(test2,file = "test2.csv")
write.csv(test3,file = "test3.csv")
# shiny part
library(shiny)
ui <- fluidPage(
# useShinyjs(),
sidebarLayout(
sidebarPanel(
fileInput(
inputId = "files",
label = "Choose CSV File",
multiple = TRUE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
tags$hr(),
selectInput("type", "Choose Data:", choices = c('Noheader'=TRUE,'Header'=FALSE)),
tags$hr(),
actionButton("update", "show",class = "btn btn-primary btn-lg",icon = icon("refresh"), width = "120px"),
),
mainPanel(
uiOutput("mytabs"),
textOutput("text_null", container = h4)
)
)
)
server <- function(input, output, session){
values <- reactiveValues(file_data=NULL)
filedata <- eventReactive(input$update, {
req(input$files)
upload = list()
for(nr in 1:length(input$files[, 1])){
raw_name <- sub(".csv$", "",input$files[[nr, 'name']])
upload[[raw_name]] <- read.csv(file = input$files[[nr, 'datapath']],header = as.logical(input$type))
}
return((upload))
})
output$mytabs = renderUI({
values$file_data <- filedata()
nTabs <- length(filedata())
tabNames <- names(values$file_data)
myTabs = lapply(1: nTabs, function(i) {
tabPanel( tabNames[i],
tags$div(class = "group-output",
tags$br(),
tableOutput(paste0("Group",i))#))
)
)
})
do.call(tabsetPanel, myTabs)
})
observe({
values$file_data <- filedata()
nn_Tabs <- length(filedata())
progress <<- shiny::Progress$new()
on.exit(progress$close())
progress$set(message = "Begin to process data", value = 0)
for (i in 1: nn_Tabs){
local({
my_n <- i
TableName <- paste0("Group",my_n)
output[[TableName]] <- renderTable({ values$file_data[[my_n]] })
print(values$file_data[[my_n]])
progress$inc(1/nn_Tabs, detail = ", Please wait...")
})
}
progress$set(message = "Finished!", value = 1)
})
}
shinyApp(ui, server)

Related

How to set up actionButton() or actionBttn() to clear all selections in pickerInput()

When I click on the Action Button, I would like to clear everything: both the output and the selections in the picketInput() (input$engine and input$cylinder in the code below). For consistency if I can do it with shinyWidget's actionBttn, that will be great as well.
library(shiny)
library(shinyWidgets)
df <- mtcars
ui <- fluidPage(
sidebarPanel(
pickerInput("engine", "Select engine:", choices = unique(df$vs),
options = list(
`actions-box` = TRUE),
multiple = TRUE
),
pickerInput("cylinder", "Select cylinder:", choices = unique(df$cyl),
options = list(
`actions-box` = TRUE),
multiple = TRUE
),
actionButton("reset", "Clear Selection"),
),
mainPanel(
textOutput("results")
)
)
server <- function(input, output, session) {
data <- reactiveValues()
observeEvent(input$cylinder, {
tmp <- df
tmp1 <- tmp[tmp$vs %in% input$engine, ]
tmp2 <- tmp1[tmp1$cyl %in% input$cylinder, ]
data$tmp2 <- tmp2
})
output$results <- renderText({
if(is.null(data$tmp2)) return()
print(row.names(data$tmp2))
})
observeEvent(input$reset, {
updatePickerInput(session, "engine", NULL)
updatePickerInput(session, "cylinder", NULL)
data$tmp2 <- NULL
})
}
shinyApp(ui = ui, server = server)
You'll have to respect the order of updatePickerInput's parameters or name them. Your above approach would have updated the label.
Please see ?updatePickerInput and check the following:
library(shiny)
library(shinyWidgets)
library(datasets)
DF <- mtcars
ui <- fluidPage(
sidebarPanel(
pickerInput("engine", "Select engine:", choices = unique(DF$vs),
options = list(
`actions-box` = TRUE),
multiple = TRUE
),
pickerInput("cylinder", "Select cylinder:", choices = unique(DF$cyl),
options = list(
`actions-box` = TRUE),
multiple = TRUE
),
actionBttn("reset", "Clear Selection"),
),
mainPanel(
textOutput("results")
)
)
server <- function(input, output, session) {
data <- reactiveValues()
observeEvent(input$cylinder, {
tmp <- DF
tmp1 <- tmp[tmp$vs %in% input$engine, ]
tmp2 <- tmp1[tmp1$cyl %in% input$cylinder, ]
data$tmp2 <- tmp2
})
output$results <- renderText({
req(data$tmp2)
row.names(data$tmp2)
})
observeEvent(input$reset, {
updatePickerInput(session, inputId = "engine", selected = "")
updatePickerInput(session, inputId = "cylinder", selected = "")
data$tmp2 <- NULL
})
}
shinyApp(ui = ui, server = server)

How to create a button that will create a pdf file of a table

I currently have a table being generated and I would like the user to be able to create a pdf file when they click the download button.
I am currently getting an error where when I click the download button I get an html file that downloads the entire page of the app. I thought that using pdf(file) would work but it ignores the function.
Here is currently what I have.
library(shiny)
library(xlsx)
library(shinyWidgets)
population <- read.xlsx("population.xlsx", 1)
fieldsMandatory <- c("selectedCountry")
labelMandatory <- function(label) {
tagList(
label,
span("*", class = "mandatory_star")
)
}
appCSS <-
".mandatory_star {color: red;}"
ui <- fluidPage(
navbarPage(title = span("Spatial Tracking of COVID-19 using Mathematical Models", style = "color:#000000; font-weight:bold; font-size:15pt"),
tabPanel(title = "Model",
sidebarLayout(
sidebarPanel(
shinyjs::useShinyjs(),
shinyjs::inlineCSS(appCSS),
div(
id = "dashboard",
pickerInput(
inputId = "selectedCountry",
labelMandatory ("Country"),
choices = population$Country,
multiple = FALSE,
options = pickerOptions(
actionsBox = TRUE,
title = "Please select a country")
),
sliderInput(inputId = "agg",
label = "Aggregation Factor",
min = 0, max = 50, step = 5, value = 10),
actionButton("go","Run Simulation"),
)
),
mainPanel(
tabsetPanel(
tabPanel("Input Summary", verbatimTextOutput("summary"),
tableOutput("table"),
downloadButton(outputId = "downloadSummary", label = "Save Summary"))
)
)
)
)
)
)
server <- function(input, output, session){
observeEvent(input$resetAll, {
shinyjs::reset("dashboard")
})
values <- reactiveValues()
values$df <- data.frame(Variable = character(), Value = character())
observeEvent(input$go, {
row1 <- data.frame(Variable = "Country", Value = input$selectedCountry)
row2 <- data.frame(Variable = "Aggregation Factor", Value = input$agg)
values$df <- rbind(row1, row2)
})
output$table <- renderTable(values$df)
observe({
# check if all mandatory fields have a value
mandatoryFilled <-
vapply(fieldsMandatory,
function(x) {
!is.null(input[[x]]) && input[[x]] != ""
},
logical(1))
mandatoryFilled <- all(mandatoryFilled)
# enable/disable the submit button
shinyjs::toggleState(id = "go", condition = mandatoryFilled)
})
output$downloadSummary <- downloadHandler(
filename = function(file) {
paste('my-report.pdf', )
},
content = function(file) {
pdf(file)
}
)
}
shinyApp(ui,server)
Here's a minimal example:
library(shiny)
ui <- fluidPage(
downloadButton("savepdf", "Save pdf")
)
server <- function(input, output, session) {
output$savepdf <- downloadHandler(
filename = "test.pdf",
content = function(file) {
pdf(file)
plot(iris$Sepal.Length, iris$Sepal.Width)
dev.off()
}
)
}
shinyApp(ui, server)
Also see here.
Here is a minimal example with the package latexpdf. It will create the pdf table in the folder of the app.
library(shiny)
library(latexpdf)
dat <- head(iris, 5)
ui <- fluidPage(
br(),
actionButton("dwnld", "Create pdf"),
tableOutput("mytable")
)
server <- function(input, output, session){
output[["mytable"]] <- renderTable({
dat
})
observeEvent(input[["dwnld"]], {
as.pdf(dat)
})
}
shinyApp(ui, server)

Actionbutton stops display of datatable when file is uploaded for first time

I have the shiny app below in which the user uploads a csv. Then the pickerInput gets the unique values of the first column of that csv and uses them to subset the dataframe and display it in a table. The issue is that I want to use an actionButton in order to apply changes but when the csv is uploaded for first time it should be displayed full and not displayed empty because the actionButton is not triggered yet. For the purpose of the example I have used iris dataset instead of a csv.
# app.R ##
library(shiny)
library(DT)
library(shinyWidgets)
ui <- pageWithSidebar(
headerPanel('Iris k-means clustering'),
sidebarPanel(
fileInput("file1", "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
uiOutput("id"),
actionButton("go","Go")
),
mainPanel(
uiOutput('contents')
)
)
server <- function(input, output, session) {
output$id<-renderUI({
#inFile <- input$file1
#df2<-data.frame(read.csv(inFile$datapath, header = TRUE))
pickerInput("select", "Select ID",
choices = as.character(unique(iris$Species)),
multiple = T,options = list(`actions-box` = TRUE),
selected = as.character(unique(iris$Species)))
})
output$contents <- renderUI({
input$goButton
#inFile <- input$file1
#df<-data.frame(read.csv(inFile$datapath, header = TRUE))
df<-data.frame(iris)
df<-subset(iris,Species %in% isolate(input$select))
renderDataTable({
datatable(
df,
options = list(scrollX = TRUE,pageLength=5)
)
})
})
}
shinyApp(ui = ui, server = server)
library(shiny)
library(DT)
library(shinyWidgets)
ui <- pageWithSidebar(
headerPanel('Iris k-means clustering'),
sidebarPanel(
fileInput("file1", "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
uiOutput("picker"),
actionButton("go","Go")
),
mainPanel(
DTOutput("dtable")
)
)
server <- function(input, output, session) {
filteredCSV <- reactiveVal(NULL)
CSV <- eventReactive(input[["file1"]], {
dat <- read.csv(input[["file1"]]$datapath, header = TRUE)
filteredCSV(dat)
dat
})
output[["picker"]] <- renderUI({
req(CSV())
choices <- unique(as.character(CSV()[,1]))
pickerInput("select", "Select ID",
choices = choices,
multiple = TRUE, options = list(`actions-box` = TRUE),
selected = choices)
})
observeEvent(input[["go"]], {
req(CSV())
filteredCSV(CSV()[CSV()[,1] %in% input[["select"]],])
})
output[["dtable"]] <- renderDT({
req(filteredCSV())
datatable(
filteredCSV(),
options = list(scrollX = TRUE, pageLength = 5)
)
})
}
shinyApp(ui = ui, server = server)
This is in reply to the previous version of your post, but should solve the main problem - this is how I would go about it, using reactive expressions (and data.table, but you might just as well not use it):
library(shiny)
library(shinyWidgets)
library(DT)
library(data.table)
ui <- pageWithSidebar(
headerPanel('Iris k-means clustering'),
sidebarPanel(
fileInput("file1", "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
uiOutput("id"),
#actionButton("go","Go")
),
mainPanel(
DT::dataTableOutput('contents')
)
)
server <- function(input, output, session) {
getFile <- reactive({
req(input$file1)
fread(input$file1$datapath, header = TRUE)
})
output$contents <- DT::renderDataTable({
DT::datatable(getFile()[get(colnames(getFile())[1]) %in% input$select])
})
output$id <- renderUI({
req(getFile())
df <- getFile()
pickerInput("select", "Select ID",
choices = unique(df[[1]]),
multiple = TRUE, options = list(`actions-box` = TRUE),
selected = unique(df[[1]]))
})
}
shinyApp(ui = ui, server = server)

Upload a csv file with actionbutton and display a corrplot

I tried to make a web application with R::shiny but I met a problem with a piece of code. Indeed, I would like to upload a csv file and display a correlogram.
I tried to set up the correlogram with the actionbutton() followed by the updateSelectizeInput()
However an error has been occured :
Error: Unsupported index type: NULL
Anybody have a solution ? thanks
NB - I don't want to use the fileInput widget to upload the csv file ! Only by the actionbutton !
library(shiny)
library(readr)
library(corrplot)
library(DT)
# File used for the example
data(iris)
write.csv(x = iris, file = "iris.csv")
#UI
ui <- shinyUI(
fluidPage(
navbarPage(
id = "navbar",
tabPanel(
title = "UPLOAD",
br(),
actionButton(inputId = "file", label = "ADD A FILE")
)
)
)
)
#SERVER
server <- function(input, output, session) {
path <- reactiveValues(pth = NULL)
file.choose2 <- function(...) {
pathname <- NULL;
tryCatch({
pathname <- file.choose();
}, error = function(ex) {
})
pathname;
}
observeEvent(input$file,{
path$pth <- file.choose2()
})
observeEvent(input$file, {
newvalue <- "B"
updateNavbarPage(session, "navbar", newvalue)
})
data <- reactive({
df <- readr::read_csv(file = path$pth)
return(df)
})
observeEvent(input$file, {
appendTab(
inputId = "navbar",
tabPanel(
value = "B",
title = "Corr",
sidebarLayout(
sidebarPanel(
selectizeInput(
inputId = "select04",
label = "Select features",
choices = NULL,
multiple = TRUE)
),
mainPanel(
plotOutput(
outputId = "corrplot01", height = "650px")
)
)
)
)
}, once = TRUE)
# I suppose there is a problem with this line
observeEvent(input$select04, {
col <- names(data())
col.num <- which(sapply(data(), class) == "numeric")
col <- col[col.num]
updateSelectizeInput(session = session, inputId = "select04", choices = col)
})
output$corrplot01 <- renderPlot({
df <- data()
df1 <- df[,input$select04]
corr <- cor(x = df1, use = "pairwise.complete.obs")
corrplot(corr = corr,
title = "")
})
}
shinyApp(ui, server)
I changed your ui and server a bit, but I think that might solve your problem.
I deleted the observeEvent(input$file, ...{}) from the server and added the ui part in the Ui directly.
I also added 3 req() calls in the data reactive, in the second observeEvent(input$select04, ...{}) which I changed to a normal observe and in the renderPlot call.
library(shiny)
library(readr)
library(corrplot)
library(DT)
# File used for the example
data(iris)
write.csv(x = iris, file = "iris.csv", row.names = F)
#UI
ui <- shinyUI(
fluidPage(
navbarPage(
id = "navbar",
tabPanel(
title = "UPLOAD",
br(),
actionButton(inputId = "file", label = "ADD A FILE"),
tabPanel(
value = "B",
title = "Corr",
sidebarLayout(
sidebarPanel(
selectizeInput(width = "300px",
inputId = "select04",
label = "Select features",
choices = NULL,
multiple = TRUE)
),
mainPanel(
plotOutput(
outputId = "corrplot01", height = "650px")
)
)
)
)
)
)
)
#SERVER
server <- function(input, output, session) {
path <- reactiveValues(pth = NULL)
file.choose2 <- function(...) {
pathname <- NULL;
tryCatch({
pathname <- file.choose();
}, error = function(ex) {
})
pathname;
}
observeEvent(input$file,{
path$pth <- file.choose2()
})
observeEvent(input$file, {
newvalue <- "B"
updateNavbarPage(session, "navbar", newvalue)
})
data <- reactive({
req(path$pth)
df <- readr::read_csv(file = path$pth)
return(df)
})
# I suppose there is a problem with this line
observe({
req(names(data()))
col <- names(data())
col.num <- which(sapply(data(), class) == "numeric")
col <- col[col.num]
updateSelectizeInput(session = session, inputId = "select04", choices = col)
})
output$corrplot01 <- renderPlot({
req(input$select04)
df <- data()
df1 <- df[,input$select04]
corr <- cor(x = df1, use = "pairwise.complete.obs")
corrplot(corr = corr,
title = "")
})
}
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