'Uploading zip with multiple files into a shiny application

I am trying to upload a zip file through my shiny app that contains a bunch of xml files in it, and then process them. My code looks something like this:

library(shiny)

parse_xml <-function(FileName) {
  a <- xmlParse(FileName)
  xmlToDataFrame(a, stringsAsFactors = FALSE) %>%
    fill(Description, Min, Max, id, StartDateTime,
         EndDateTime, .direction = "up") %>%
    na.omit()
}

ui <- fluidPage(
  column(width = 4,
         fileInput("upload", "Upload", accept = ".zip")),
  column(width = 4,
         br(),
         actionButton("process", "Process uploaded data"))
)

server <- function(input, output) {
  observeEvent(input$process, {
    files <- unzip(input$upload, list = TRUE)

    Data <- ldply(unz(input$upload, files$Name[2:length(files$Name)]), parse_xml)
  })
}

shinyApp(ui = ui, server = server)

At the first step of trying to unzip file, I already get an error:

Warning: Error in unzip: invalid zip name argument

Does anyone have any idea on how I can fix this?

UPD: The first error was fixed by changing input$upload to input$upload$datapath. The new error:

Error in unz: invalid 'description' argument


Solution 1:[1]

It should be files <- unzip(input$upload$name, list = TRUE) instead of unzip(input$upload, list = TRUE)

Solution 2:[2]

This does what I intended to do, in case anyone else needs it:

library(shiny)
library(dplyr)

parse_xml <-function(FileName) {
  a <- xmlParse(FileName)

  print(1)

  xmlToDataFrame(a, stringsAsFactors = FALSE) %>%
    fill(Description, Min, Max, id, StartDateTime,
         EndDateTime, .direction = "up") %>%
    na.omit()
}

ui <- fluidPage(
  column(width = 4,
         fileInput("upload", "Upload", accept = ".zip")),
  column(width = 4,
         br(),
         actionButton("process", "Process uploaded data"))
)

server <- function(input, output) {
  observeEvent(input$process, {
    files <- unzip(input$upload$datapath, list = TRUE)

    unzip_xml <- function(i) {parse_xml(readLines(unz(input$upload$datapath, files$Name[i])))}

    data <- lapply(1:length(files$Name), unzip_xml)

    data1 <- bind_rows(data)
  })
}

shinyApp(ui = ui, server = server)

Solution 3:[3]

Here's a solution that works with shapefiles. It takes the zip folder with minimum included (.shp, .prj, .dbf, .shx ) , unzips it in your working directory, then reads the .shp file into a Simple Features object.

You don't need to assign the files to a variable, just read the .shp after extraction.

library(sf)
library(shiny)
library(rgdal)

ui <- fluidPage(

    sidebarLayout(
        sidebarPanel(
            fileInput( inputId = "upload", label = "Input Shapefile .zip", multiple = TRUE, accept = '.zip' )
        ),
        mainPanel(
            shiny::verbatimTextOutput("shpdata")
        )
    )
)

server <- function(input, output, session) {

    observe({ 
        shpdf <- input$upload
        req(input$upload)
        unzip(input$upload$datapath)
        shp <- rgdal::readOGR(paste(getwd(), list.files(pattern = "*.shp$"), sep="/"), verbose = FALSE)
        shp <- sf::st_as_sf(shp)

    output$shpdata <- renderPrint(shp)
})

}

shinyApp(ui = ui, server = server)


Simple feature collection with 1 feature and 1 field
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -360 ymin: 0.0000 xmax: -0.0000 ymax: 360.0000
Geodetic CRS:  WGS 84
  FID                       geometry
0   0 POLYGON ((-000.0000 00.0000...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SBista
Solution 2 Galina Polishchuk
Solution 3 user2863275