Reputation: 1311
I am building web app that after uploading csv files transforms the data and then should be able to output few tables. The number of the tables depends strictly on the information included in the csv files, therefore is calculated during the data transformation process. I have created a list lst
with data frames that have to be outputted. The length of the list is the number of the tables that should be created. After searching the web I encountered very similar question (here), which is unfortunately not answered yet. Does anyone has an idea how to solve it?
Some of my code (not all, due to significant data transformation), where I would like to replace fixed max_table
with variable length(data_set())
:
library(shiny)
ui <- fluidPage(
fluidRow(column(3,
wellPanel(
fileInput(inputId = "files",
label = "Choose cvs files",
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv'),
multiple = TRUE))),
column(5, offset = 1,
uiOutput("tables")
)
)
)
max_table <- 5
server <- function(input,output){
data_set <- reactive({
if(is.null(input$files)){
return(NULL)
}
lst <- list()
for(i in 1:length(input$files[,1])){
lst[[i]] <- read.csv(input$files[[i, 'datapath']], sep = ",", header = TRUE, skip = 4, dec = ".")
}
lst
})
output$tables <- renderUI({
plot_output_list <- lapply(1:max_table, function(i) {
tablename <- paste("tablename", i, sep="")
tableOutput(tablename)
})
do.call(tagList, plot_output_list)
})
for (i in 1:max_table){
local({
my_i <- i
tablename <- paste("tablename", my_i, sep="")
output[[tablename]] <- renderTable({data_set()[[my_i]]
})
})
}
}
shinyApp(ui = ui, server = server)
Any help would be much appreciated!
Upvotes: 2
Views: 2568
Reputation: 12107
A solution is to put everything inside an observe
.
library(shiny)
ui <- fluidPage(
fluidRow(column(3,
wellPanel(
fileInput(
inputId = "files",
label = "Choose cvs files",
accept = c('text/csv',
'text/comma-separated-values,text/plain',
'.csv'),
multiple = TRUE
)
)),
column(5, offset = 1, uiOutput("tables"))))
server <- function(input, output) {
observe({
if (!is.null(input$files)) {
max_table = length(input$files[, 1])
lst <- list()
for (i in 1:length(input$files[, 1])) {
lst[[i]] <-
read.csv(
input$files[[i, 'datapath']],
sep = ",",
header = TRUE,
skip = 4,
dec = "."
)
}
output$tables <- renderUI({
plot_output_list <- lapply(1:max_table, function(i) {
tablename <- paste("tablename", i, sep = "")
tableOutput(tablename)
})
do.call(tagList, plot_output_list)
})
for (i in 1:max_table) {
local({
my_i <- i
tablename <- paste("tablename", my_i, sep = "")
output[[tablename]] <- renderTable({
lst[[my_i]]
})
})
}
}
})
}
shinyApp(ui = ui, server = server)
Upvotes: 3