I'm working on a shiny app to manipulate data. I'd like to read a zip file selectioned in a fileInput. This zip is composed by multiple csv files, and I'd like to save as reactive values all .csv dataframes. For example, if test.zip contains file ONE.csv, TWO.csv, THREE.csv , i'd like to obtain 3 reactives values (as dataframes) called ONE , TWO, THREE .
I'm abble to do it if I know the name and number of csv files.
But if I don't know the number and names of .csv dataframes, how can I achieve it ?
## Only run examples in interactive R sessions
if (interactive()) {
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("ZIP", "Choose ZIP File",
accept = ".zip"
)
),
mainPanel(
DT::dataTableOutput("ONEtab")
)
)
)
server <- function(input, output) {
ONE <- reactive({
inFile <-req(input$ZIP)
read_csv(unzip(inFile$datapath,"ONE.CSV"))
})
TWO <- reactive({
inFile <-req(input$ZIP)
read_csv(unzip(inFile$datapath,"TWO.CSV"))
})
THREE <- reactive({
inFile <-req(input$ZIP)
read_csv(unzip(inFile$datapath,"THREE.CSV"))
})
output$ONEtab <- DT::renderDataTable({ DT::datatable(ONE(), option=list(scrollX=T),filter = 'top')})
}
shinyApp(ui, server)
}
Thanks for your help !
One option is to read all the dataframes into a single variable and then use a number to select the one of interest. Here's some code that does this. It uses lapply
to read the contents of the zip file to create a reactive variable called all
. To reference different dataframes, the code required is all()[[index]]
and I have added something that shows this.
library(DT)
library(readr)
ui <- fluidPage(sidebarLayout(sidebarPanel(
fileInput("ZIP", "Choose ZIP File", accept = ".zip"),
selectInput("choice", 'Choose', choices = c(1,2,3), selected = 1)
),
mainPanel(DT::dataTableOutput("selectone"))))
server <- function(input, output) {
all <- reactive({
inFile <- req(input$ZIP)
filelist <- unzip(inFile$datapath, list = T)
lapply(filelist$Name, read_csv)
})
output$selectone <-
DT::renderDataTable({
choice = as.integer(input$choice)
DT::datatable(all()[[choice]], option = list(scrollX = T), filter = 'top')
})
}
shinyApp(ui, server)
Without the rest of your code that processes this, it's difficult to know if this will be what you need but perhaps it's a start.