将大xlsx文件导入R中?


75

我想知道是否有人知道从“大” xlsx文件(〜20Mb)导入数据的方法。我尝试使用xlsx和XLConnect库。不幸的是,它们都使用rJava,并且我总是会遇到相同的错误:

> library(XLConnect)
> wb <- loadWorkbook("MyBigFile.xlsx")
Error: OutOfMemoryError (Java): Java heap space

要么

> library(xlsx)
> mydata <- read.xlsx2(file="MyBigFile.xlsx")
Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl,  : 
   java.lang.OutOfMemoryError: Java heap space

我还尝试在加载rJava之前修改java.parameters:

> options( java.parameters = "-Xmx2500m")
> library(xlsx) # load rJava
> mydata <- read.xlsx2(file="MyBigFile.xlsx")
Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl,  : 
   java.lang.OutOfMemoryError: Java heap space

或加载rJava之后(我认为这有点愚蠢):

> library(xlsx) # load rJava
> options( java.parameters = "-Xmx2500m")
> mydata <- read.xlsx2(file="MyBigFile.xlsx")
Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl,  : 
   java.lang.OutOfMemoryError: Java heap space

但是没有任何效果。有人有主意吗?


6
您是否考虑过将数据保存为更通用的格式,例如csv?
flodel 2013年

3
gdata是另一种选择。我相信它不是基于Java的,但是我可能会误会。
里卡多·萨波特塔

2
为什么这么大?很多行(是否全部需要它们?),很多列(全部需要它们吗?),很多单张纸(全部需要它们吗?),一张高分辨率的嵌入式图像(您不需要那个) ...)?对于电子表格和其他二进制文件,以字节为单位的文件大小通常不是衡量其中数据实际大小的有用方法。
Spacedman

3
gdata运作...非常缓慢,每页约7分钟,但运作正常。
2013年

3
我一直在努力导入同事的,庞大的,带有公式的Excel文件(150 MB),并且gdata是唯一可以将其提取的Excel软件包。如此处所示,基于Java的程序包内存不足。openxlsx断断续续的。gdata每张纸花了30分钟,但完成了工作。
马特·帕克

Answers:


141

当有人给我(另一个)Excel文件进​​行分析时,我偶然发现了这个问题。这个甚至还没有那么大,但是由于某种原因,我遇到了类似的错误:

java.lang.OutOfMemoryError: GC overhead limit exceeded

基于@Dirk Eddelbuettel在先前答案中的评论,我安装了openxlsx软件包(http://cran.r-project.org/web/packages/openxlsx/)。然后运行:

library("openxlsx")
mydf <- read.xlsx("BigExcelFile.xlsx", sheet = 1, startRow = 2, colNames = TRUE)

这正是我想要的。易于使用和邪恶的快速。这是我的新朋友。感谢小费@Dirk E!

顺便说一句,我不想​​从Dirk E那里窃取这个答案,所以如果他发布答案,请接受它而不是我的!


我尝试了许多方法来读取大的.xslx文件,但似乎没有任何效果。当我在github上使用Schaun Wheeler的函数时遇到错误,并且无法弄清楚如何在gdata中为我的计算机使用perl命令。“openxlsx”就是这样对我来说是生命的救星感谢@Dirk Eddelbuettel和奥维尔·杰克逊。
nasia jaffri

您知道其他解决方案吗?我找不到用openxlsx打开.xls文件的方法
user124123 2015年

您可以尝试使用gdata包中的read.xls函数。我自己从未使用过,但值得一试。
奥维尔·杰克逊

1
openxlsx是唯一适用于我的excel文件(70Mo)的库。但我必须先将.xls转换为.xlsx
agenis

OpenXLSX具有无法识别日期的缺点。对我来说,从readxl包中读取read_excel似乎是一种方法。
同peer

15
options(java.parameters = "-Xmx2048m")  ## memory set to 2 GB
library(XLConnect)

在加载任何Java组件之前,请使用“选项”提供更多内存。然后加载XLConnect库(它使用Java)。

而已。开始使用readWorksheet ....等读取数据。:)


2
谢谢你的提示。重要注意事项:在R-Studio中使用它时,我必须在发行options(java.parameters = "-Xmx2048m")前发行require('rJava')。不幸的是,现在我遇到了一个新错误:“ java.lang.OutOfMemoryError:超出了GC开销限制”,但是我确定这是一个不同的问题。
pbnelson

这为我工作,但我也必须确保我的[R版本匹配我的Java版本(例如64位),并正确设置了Java路径:options(java.parameters="-Xmx4g") # increase java memorySys.setenv(JAVA_HOME='C:\\Program Files\\Java\\jdk-11.0.2') # for 64-bit versionlibrary(rJava) # check it works
西蒙·伍德沃德

8

我同意@orville jackson的回复,它也确实对我有帮助。

内联@orville jackson提供的答案。这是如何使用openxlsx的详细说明读取和写入大文件。

当数据量较小时,R具有许多可根据您的要求使用的软件包和功能。

write.xlsx,write.xlsx2,XLconnect也可以完成工作,但是与openxlsx相比,这些有时速度较慢。

因此,如果您处理的是大型数据集,并且遇到了Java错误。我建议看看“ openxlsx”,它真的很棒,可以将时间减少1/12。

我已经进行了全部测试,最后,openxlsx功能的性能给我留下了深刻的印象。

以下是将多个数据集写入多个工作表的步骤。

install.packages("openxlsx")
library("openxlsx")

start.time <- Sys.time()

# Creating large data frame
x <- as.data.frame(matrix(1:4000000,200000,20))
y <- as.data.frame(matrix(1:4000000,200000,20))
z <- as.data.frame(matrix(1:4000000,200000,20))

# Creating a workbook
wb <- createWorkbook("Example.xlsx")
Sys.setenv("R_ZIPCMD" = "C:/Rtools/bin/zip.exe") ## path to zip.exe

Sys.setenv(“ R_ZIPCMD” =“ C:/Rtools/bin/zip.exe”)必须是静态的,因为它引用了Rtools的某些实用程序。

注意:如果您的系统上未安装Rtools,请先安装Rtools以获得流畅的体验。这是供您参考的链接:(选择适当的版本) https://cran.r-project.org/bin/windows/Rtools/

按照下面的链接检查选项(安装时需要选中所有复选框) https://cloud.githubusercontent.com/assets/7400673/12230758/99fb2202-b8a6-11e5-82e6-836159440831.png

# Adding a worksheets : parameters for addWorksheet are 1. Workbook Name 2. Sheet Name

addWorksheet(wb, "Sheet 1")
addWorksheet(wb, "Sheet 2")
addWorksheet(wb, "Sheet 3")

# Writing data in to respetive sheets: parameters for writeData are 1. Workbook Name 2. Sheet index/ sheet name 3. dataframe name

writeData(wb, 1, x)

# incase you would like to write sheet with filter available for ease of access you can pass the parameter withFilter = TRUE in writeData function.
writeData(wb, 2, x = y, withFilter = TRUE)

## Similarly writeDataTable is another way for representing your data with table formatting:

writeDataTable(wb, 3, z)

saveWorkbook(wb, file = "Example.xlsx", overwrite = TRUE)

end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

openxlsx软件包非常适合从excel文件中读取/写入大量数据,并且在excel中具有许多用于自定义格式的选项。

有趣的事实是,我们在这里不必为Java堆内存而烦恼。


经过测试的read.xlsx2,XLConnect,readxl和openxlsx和openxlsx的速度比其他产品快很多倍
阿里(Ali)

7

我知道这个问题有点老了,但是现在有一个很好的解决方案。当您尝试使用GUI在Rstudio中导入excel时,这是默认程序包,在我的情况下效果很好。

library(readxl)

data <- read_excel(filename)

5

正如规范的Excel-> R问题中提到的那样,该readxl软件包中出现了一个最新的替代方法,与例如和相比,我发现它非常快。openxlsxxlsx

也就是说,电子表格有一个明确的限制,超过该限制后,最好将其另存为.csv并使用fread


3

我在xlsx::read.xlsx和中也有相同的错误XLConnect::readWorksheetFromFile。也许您可以使用RODBC::odbcDriverConnectRODBC::sqlFetch,后者使用Microsoft RODBC,效率更高。


2

@flodel关于转换为CSV的建议似乎最简单。如果出于某种原因这不是一个选择,则可以分块读取文件:

 require(XLConnect)
 chnksz <- 2e3
 s <- <sheet>
 wb <- loadWorkbook(<file>, s)
 tot.rows <- getLastRow(wb)
 last.row =0
 for (i in seq(ceiling( tot.rows / chnksz) )) {
    next.batch <- readWorksheet(wb, s, startRow=last.row+i, endRow=last.row+chnksz+i)
    # optionally save next.batch to disk or 
    # assign it to a list. See which works for you. 
 } 

不幸的是,该loadWorkbook命令生成一个“ OutOfMemoryError”。基于相同的想法,我尝试了mydata.chunk = read.xlsx2(file="MyBigFile.xlsx", sheetIndex=1, startRow=1, endRow=10),但仍然是相同的错误。
user2722443

@ user2722443,是否要保存已读的部分,然后将其从内存中删除?也尝试gc()在每个for循环中运行。它会使您减速,但会清除一些内存。顺便说一句,您确定无法转换为CSV吗?
里卡多·萨波特塔

1
@ {Ricardo Saporta}实际上会mydata.chunk = read.xlsx2(file="MyBigFile.xlsx", sheetIndex=1, startRow=1, endRow=10)生成一个“ OutOfMemoryError”。因此,我无法删除任何内容。关于CSV转换,这并不是完全没有问题,而是外部操作(在R中加载之前)。
user2722443

0

我发现此线程正在寻找完全相同的问题的答案。而不是尝试从R中入侵xlsx文件,最终对我有用的是使用python将文件转换为.csv,然后使用标准扫描功能将文件导入R。

签出:https : //github.com/dilshod/xlsx2csv


1
...这在R的gdata包中已经存在了十年(但在后台使用了Perl)。
Dirk Eddelbuettel 2014年

当我使用gdata解决问题时,它的速度慢得令人无法接受。这个python脚本极其快速地转换了大型xlsx文件
2014年

1
这个答案与另一个答案中提到的@flodel的建议有何不同?IMHO RODBC与中间CSV格式相比没有什么优势。
mlt

8
还有一个新手正在开发中:openxlsx仅使用Rcpp,仅使用C ++代码,并且声称速度很快。不知道它有多精致。
Dirk Eddelbuettel 2014年

您为什么不只在excel中打开它并导出为CSV?
MattE'7
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.