R中非常缓慢或失败的xls数据提取[功能read.xls,read_xls,xlsx2等]

问题描述 投票:0回答:2

我有多个.xls(〜100MB)文件,我想从中将一张纸(实际上只是一列数字)加载到R中作为数据帧。我已经尝试了各种功能,例如xlsx::xlsx2XLConnect::readWorksheetFromFile,它们都始终运行很长时间(> 15分钟),并且从未完成,因此我不得不强制退出RStudio才能继续工作。

我也尝试过gdata::read.xls,它确实完成了我想要的操作,但是每个文件花费3分钟以上。这些函数执行所需的时间(而且我什至不能确定如果让它们运行更长的时间,前两个函数是否会完成)对于我的管道来说太长了,我需要一次处理多个文件。有没有办法让它们更快地运行?

[在很多地方,我看到了使用函数readxl::read_xls的建议,该函数似乎被广泛推荐用于此任务,并且应该更快(这也是我希望的)。但是,这给了我一个错误:

> # Minimal reproducible example:
> setwd("/Users/USER/Desktop")
> library(readxl)
> data <- read_xls(path="test_file.xls")
Error: 
  filepath: /Users/USER/Desktop/test_file.xls
  libxls error: Unable to open file

我还进行了一些基本测试,以确保文件存在并且格式正确:

> # Testing existence & format of the file
> file.exists("test_file.xls")
[1] TRUE
> format_from_ext("test_file.xls")
[1] "xls"
> format_from_signature("test_file.xls")
[1] "xls"

以上使用的test_file.xls可用于here。任何建议都会使第一个功能运行得更快或read_xls完全运行-谢谢!

r excel macos xls readxl
2个回答
1
投票

我下载了您的数据集并以这种方式读取了每个excel工作表(例如,工作表“总体”和“区域”):

install.packages("readxl")
library(readxl)
library(data.table)

dt_overall <- as.data.table(read_excel("test_file.xls", sheet = "Overall"))
area_sheet <- as.data.table(read_excel("test_file.xls", sheet = "Area"))

最后,我得到像这样的dt(例如,“区域”表的数据集的一部分):

enter image description here

同样,您可以使用read_xls功能代替read_excel

我检查过,它也可以正常工作,甚至更快一些,因为read_excelread_xls程序包中read_xlsxreadxl函数的包装。

此外,您也可以使用excel_sheets包中的readxl功能来读取Excel文件的所有工作表。


0
投票

我将提出不同的工作流程。如果您恰好安装了LibreOffice,则可以通过编程将excel文件转换为csv。我有Linux,所以我可以在bash中进行操作,但是我确信它可以在macOS中使用。

因此打开一个终端,并导航至包含您的excel文件的文件夹,然后在终端中运行:

for i in *.xls
    do soffice --headless --convert-to csv "$i" 
done

现在在[[R中,您可以使用data.table::fread循环读取文件:

方案1:文件的结构不同

如果文件的结构不同,则您不希望将它们一起rbind。您可以在

R

:中运行files <- dir("path/to/files", pattern = ".csv") all_files <- list() for (i in 1:length(files)){ fileName <- gsub("(^.*/)(.*)(.csv$)", "\\2", files[i]) all_files[[fileName]] <- fread(files[i]) }
如果要在列表

放入全局环境中提取命名元素,以便可以将其转换为对象,则可以使用list2env

list2env(all_files, envir = .GlobalEnv)
[请注意两件事:首先,在gsub调用中,斜线的方向。其次,如果list2env与列表中的命名元素具有相同的名称,则它们可能会覆盖全局环境中的对象。

方案2:文件的结构相同

在这种情况下,您可能想一起将它们全部rbind。您可以在

R

:中运行files <- dir("path/to/files", pattern = ".csv") joined <- list() for (i in 1:length(files)){ joined <- rbindlist(joined, fread(files[i]), fill = TRUE) }
© www.soinside.com 2019 - 2024. All rights reserved.