William
William

Reputation: 402

Uploading multiple files in Shiny, process the files, rbind the results and return a download

I need to upload multiple csv files (dummy multiple files) and apply some operations to each of the files, and then merge the resultant dataframes into one dataframe and download the output as csv file. My raw R code works but I need to put it on shiny in order to automate the process, but somehow when I uploaded two files, I got this error: "subscript out of bounds". Help will be appreciated. This is my original raw R Code that worked:

 files = list.files("G:/JSON to CSV/merge")
 numfiles = nrow(inFile)
 kata_csv1 = list()
 for (i in 1:numfiles)
 {
   kata_csv = function(y){
   JSON_csv = read.csv(y, header = TRUE)
   lastrow = nrow(JSON_csv)
   shift = function(x, n){
    c(x[-(seq(n))], rep(NA, n))
    }
  JSON_csv$companyID1 = shift(JSON_csv$companyID1, 1)
  JSON_csv = JSON_csv[-lastrow, ]
  JSON_csv 
  }
 kata_csv1[[i]] = kata_csv(files[i])
 }

 myMergedData = do.call(rbind, kata_csv1)
 write.csv(myMergedData, "myMergedData.csv", row.names=FALSE)

Here is my Shiny code that did not work:

UI.R:

  ui <- fluidPage(
   fluidPage(
     titlePanel("MY CSV FILES MERGER"),
     sidebarLayout(
       sidebarPanel(
         fileInput("file1",
              "Choose CSV files from directory",
              multiple = TRUE,
              accept=c('text/csv', 
                       'text/comma-separated-values,text/plain', 
                       '.csv')),
         downloadButton('downloadData', 'Download')
       ),
       mainPanel(
         tableOutput('contents')
       )
     )
   )
 )

Server.R:

 library(shiny)
 library(dplyr)
 function(input, output) {
   getData <- reactive({
     inFile <- input$file1
     if (is.null(inFile)){
     return(NULL)
     } else {
  numfiles = length(inFile) 
  kata_csv1 = list()
  for (i in 1:numfiles)
  {

      JSON_csv = read.csv(input$file1[[i, 'datapath']], header = TRUE)
      lastrow = nrow(JSON_csv)
      shift = function(x, n){
        c(x[-(seq(n))], rep(NA, n))
      }
      JSON_csv$companyID1 = shift(JSON_csv$companyID1, 1)
      kata_csv1[[i]] = JSON_csv[-lastrow, ]

    }
    do.call(rbind, kata_csv1)
   }
   })
   output$contents <- renderTable( 
   getData() 
   )
   output$downloadData <- downloadHandler(
    filename = function() { 
    paste("data-", Sys.Date(), ".csv", sep="")
   },
   content = function(file) { 
   write.csv(getData(), file, row.names=FALSE)   
  })
  }

Upvotes: 0

Views: 4033

Answers (1)

SBista
SBista

Reputation: 7704

The error is because the numfiles that you are calculating as numfiles = length(inFile) gives you the number of column in your inFile dataframe. You'll instead have to use numfiles = nrow(inFile) as the number of rows in the dataframe gives you the number of files that you have uploaded.

[EDIT]: The code that is working for me is:

 library(shiny)
  library(dplyr)
 server <-  function(input, output) {
    getData <- reactive({
      inFile <- input$file1
      if (is.null(inFile)){
        return(NULL)
      }else {
        # browser()
        numfiles = nrow(inFile) 
        kata_csv1 = list()


        for (i in 1:numfiles)
        {

          JSON_csv = read.csv(input$file1[[i, 'datapath']], header = TRUE)
          lastrow = nrow(JSON_csv)
          shift = function(x, n){
            c(x[-(seq(n))], rep(NA, n))
          }
          JSON_csv$companyID1 = shift(JSON_csv$companyID1, 1)
          kata_csv1[[i]] = JSON_csv[-lastrow, ]

        }
        # browser()
        do.call(rbind, kata_csv1)
      }
    })
    output$contents <- renderTable( 
      getData() 
    )
    output$downloadData <- downloadHandler(
      filename = function() { 
        paste("data-", Sys.Date(), ".csv", sep="")
      },
      content = function(file) { 
        write.csv(getData(), file, row.names=FALSE)   
      })
  }

 shinyApp(ui = ui, server = server)

Upvotes: 3

Related Questions