【问题标题】:Reading multiple xlsx files and merging into dataframe in R读取多个 xlsx 文件并合并到 R 中的数据框
【发布时间】:2017-07-11 21:02:01
【问题描述】:

我正在编写代码:

  • 读取文件夹列表

  • 从列表中对包含特定文本元素的文件夹进行排序和提取

  • 从每个文件夹中获取完整的文件名

  • 在每个文件中找到标签/表格

  • 在我的嵌套文件列表上循环/lapply read.xlsx()

最终目标是从各自文件夹中的各自文件中读取所有选项卡/工作表,同时创建列来识别它们来自哪个选项卡/工作表以及它们来自哪个文件夹,以及然后将它们一次性合并。

我首选的 excel 文件读取包是“openxlsx”。

这是我获取文件夹和文件的代码:

path<- "/Users/jackserna/Google Drive/Folder"
dataFolders<- list.files(path)
dataFolders<- sort(dataFolders[starts_with(match = "FY", vars = dataFolders)])
files<- lapply(lapply(dataFolders, FUN = function(x){
     paste(path,x,sep = "/")
     }), FUN = function(x){
          list.files(x, pattern = "*.xlsx", full.names = TRUE)
 })

我无法为我的所有文件和所有工作表循环/应用读取功能。我会阅读不超过 1 个文件夹,这将不得不重复。我使用了来自this post的一些代码...

data.to.merge <- lapply(lapply(files[[1]], FUN = function(x){
     read.xlsx(x, sheet = 3, cols = 1:5)
}), na.omit)
merged.daata <- Reduce(function(...) merge(..., all = T), data.to.merge) 

但是,这种方法不允许我将工作表名称附加为我读入的每张工作表的额外列。这种方法假设工作表 #3 上有数据,但令我沮丧的是,这些文件并非如此.数据分散在工作表中,必须忽略某些工作表才能合并。

为了尝试抓取所有表格并解析出我不想要的表格,执行以下操作:

allsheets<- list()
for(i in files){
  for(j in i){
    sheets<- getSheetNames(j)
    allsheets<- cbind(allsheets,sheets)
  }
}

但这已经变成了一场噩梦,无法用于阅读和合并。

如何让 R 理解我想要完成的任务?

【问题讨论】:

    标签: r loops merge xlsx


    【解决方案1】:

    我无法解决这个特殊的数据清理噩梦,但在为明年做准备时,我对文件结构进行了一些更改。我发现 data.table 包对于将嵌套列表引入数据框之类的东西非常有用。

    请注意,下面的所有数据仅从 1 个指定的工作表名称(或编号)中读取。

    ### Get list of folder names
    dataFolders<- list.files(path = path)
    dataFolders<- sort(dataFolders[starts_with(match = "FY", vars = dataFolders)])
    
    ### Get list of files for each regional folder
    files<- lapply(lapply(dataFolders, FUN = function(x){
         paste(path,x,sep = "/")}), FUN = function(x){
              list.files(x, pattern = "*.xlsx", full.names = TRUE)
    })
    
    dataPrep<- lapply(files, FUN = function(x){
         lapply(lapply(x, FUN = function(x){
              read.xlsx(x, sheet = "Sheet Name", cols = 1:6)}), na.omit)
    })
    transform<- rbindlist(lapply(dataPrep, FUN = function(x){
         rbindlist(x, use.names = TRUE)
    }), use.names = TRUE) 
    

    没有噩梦般的解决方案,但它应该成为数据输入的标准。

    【讨论】:

      【解决方案2】:

      我还可以推荐包readxl。它可能无法检测工作表中的工作表数量,但您可以在使用 XLConnect 找到工作表后使用它。

      library(data.table)
      my.monthly.excel.files <-  "../../../../../../Documents/Output/Monthly/"
      my.file.list <- data.table(File.Name = list.files(path = my.monthly.excel.files , pattern = ".xlsx$" , recursive = FALSE, include.dirs = FALSE))
      rbindlist(lapply(my.file.list[,File.Name], function(file){print(file); read_excel(path = paste0(my.monthly.excel.files, file), sheet = "sheet_name")}))
      

      为了消除警告,我将要导入的每一列的列类型定义为文本、数字或日期。

      【讨论】:

      • 我尝试过 openxlsx、XLconnect 和 readxl,但对已弃用的功能感到失望。 XLconnect 似乎工作得更加一致。供大家参考,我使用的是 R 版本 3.3.2、openxlsx 版本 4.0.0、XLconnect 版本 0.2-12 和 readxl 版本 0.1.1。请不要使用不推荐使用的函数,如 data.table 或 rbindlist ,除非您指定正在运行的版本。我以为您的意思是 tbl_df(),但这没有意义,尽管使用您的语法“my.file.list[,File.Name]”确实有意义。至于我收到的输出:Error: corrupt data frame
      • 嗯,data.tablerbindlist 这两个命令是 data.table 包的一部分。现在添加了对它的调用,因为它们没有被弃用。
      【解决方案3】:

      我会对你的单独函数保持离散,这样你就可以追查哪里出了问题,也让 R 有机会在你的 Excel 包之后进行清理,这将是内存密集型的。如果您将所有内容都集中到一个命令中,它将陷入困境并崩溃。

      一旦您使用自己喜欢的包将sheet_list 读入内存,就应该这样做:

      for (i in sheet_list({
      new_sheet<- your_read_command(sheet_list[i])
           #subsitute using whatever reader package command you use likexlConnect or xlsx
      new_sheet$sheetname<- i #(adding the column with sheet name prior to binding)
      data<-rbind(data, new_sheet)
      rm(new_sheet)
      gc()}`
      

      rm()gc() 在这里非常重要。你会发现所有的 Excel 阅读器都是基于 JARS 的,而且 HOG 内存会使你的系统崩溃。绑定数据后删除每个对象,然后进行垃圾收集以防止爬行停止或彻底崩溃!

      我用 CSV 测试了这些部件,它工作正常……您现在只需要使用 Excel 包并可能稍作调整。如果您需要帮助发表评论...

      OH 和...创建 data

      【讨论】:

      • 我正在尝试这个循环:data&lt;- setNames(data.frame(matrix(ncol = 207, nrow = 0)), column_names) wksheets &lt;- list.files(recursive=T, pattern='*.xlsx') for (i in wksheets){ new_file&lt;- loadWorkbook(wksheets[i]) sheetnames&lt;- getSheets(new_file) sheetnames&lt;- sheetnames[3:length(sheetnames)] for (j in sheetnames){ sheet_list&lt;- readWorkbook(sheetnames[j], startRow = 2, colNames = FALSE) sheet_list$Reading.Center&lt;- j} data&lt;- rbind(data, sheet_list) rm(sheet_list) rm(sheetnames) gc() } 但我收到了一个模糊的错误Error: NullPointerException (Java):
      • 尝试以下解决方案:stackoverflow.com/questions/15825004/…
      猜你喜欢
      • 2018-08-18
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      • 2017-05-27
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 2015-03-30
      相关资源
      最近更新 更多