在Shiny上传多个文件,使用lapply处理文件,rbind结果并返回下载

时间:2017-10-22 10:22:53

标签: r csv shiny

在我以前的post中,我能够使用for循环在Shiny中上传多个文件,处理文件,获取结果并返回csv文件下载。感谢@SBista的贡献。但是,因为我必须一次上传大量文件(总大小约为50 - 100mb),所以我发现运行闪亮的应用程序可能会因为for循环而非常慢。我知道lapply() forlapply()循环更快,但在我的代码中应用 library(shiny) ui <- fluidPage( fluidPage( titlePanel("MY CSV FILES MERGER"), sidebarLayout( sidebarPanel( fileInput("file1", "Choose CSV files from a directory", multiple = TRUE, accept=c('text/csv', 'text/comma-separated-values,text/plain', '.csv')), downloadButton('downloadData', 'Download') ), mainPanel( tableOutput('contents') ) ) ) ) library(shiny) library(dplyr) options(shiny.maxRequestSize = 100*1024^2) server <- function(input, output) { getData <- reactive({ inFile <- input$file1 if (is.null(inFile)){ return(NULL) }else { files3 = lapply(inFile, 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 } ) do.call(rbind, files3) } }) output$contents <- renderTable( getData() ) output$downloadData <- downloadHandler( filename = function() { paste("data-", Sys.time(), ".csv", sep="") }, content = function(file) { write.csv(getData(), file, row.names=FALSE) }) } shinyApp(ui = ui, server = server) 会在运行应用后产生错误(错误:无效'说明'参数) 。任何帮助将不胜感激。这是我的reading multiple csv files,这是我的代码:

for

使用 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) 循环,此代码可以正常工作,但使用50-100mb的多个csv文件时速度非常慢:

CROSS JOIN

2 个答案:

答案 0 :(得分:1)

以下是不使用for循环的文件的可能解决方案:

 library(readxl)
    file.list <- list.files(pattern='*.xlsx')
    df.list <- lapply(file.list, read_excel)

闪亮。我在一个单独的脚本中运行我的所有文件,并使用闪亮应用程序中的“source”引用脚本

source("SCRIPTGEO.R", local = TRUE) 

这是拉动多个文件的链接。 Reading multiple files into R - Best practice

这是我在脚本中对我的应用所做的。我不是专家所以可能有其他方式...

    fils1 <- list.files(pattern = ".csv")


allquotes <- function(fils1){
  dfs <- lapply(fils1, function(x){
  df <- read.csv(x, header = T, stringsAsFactors = FALSE)
  df <- df[-c(1,nrow(df)),]
  df <- df[,c(1,2,3,5,6,7,8)]
  colnames(df) <-  c("ID", "ENTRY_DATE", "QUOTEORORDER","BILL.TO", "NAME", "BRANCH", "CONVERTED")
  return(df)
  })
  testbind <- do.call("rbind", dfs)
  return(testbind)
}

答案 1 :(得分:1)

问题是当您将lapply传递给inFile$datapath时,实际上只传递了包含文件名的第一列。相反,您需要通过 files3 = lapply(inFile$datapath, 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 } 。 lapply应该是这样的:

 n = 100

希望它有所帮助!