Імпортувати великий файл xlsx у R?


75

Цікаво, чи знає хтось про спосіб імпорту даних із "великого" файлу xlsx (~ 20 Мб). Я намагався використовувати бібліотеки 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

Я також намагався змінити java.parameters перед завантаженням rJava:

> 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?
флодель

3
gdataє ще одним варіантом. Я вважаю, що це не Java, але я можу помилитися.
Рікардо Сапорта

2
Чому він такий великий? Багато рядків (чи потрібні вони всі?), Безліч стовпців (чи потрібні вони всі?), Безліч окремих аркушів (чи потрібні вони всі?), Одне вбудоване зображення з високою роздільною здатністю (це вам не потрібно ...)? Для електронних таблиць та інших двійкових файлів розмір файлу в байтах часто не є корисним показником того, наскільки великі дані в ньому насправді.
Spacedman

3
gdataпрацює ... дуже повільно, приблизно 7 хв на аркуші, але працює.
user2722443

3
Я працював над імпортом жахливого, завантаженого формулами файлу Excel (150 МБ) і gdataбув єдиним пакетом Excel, який міг його здійснити. Як і тут, в Java-пакетах закінчилася пам'ять; openxlsxсегментний. gdataзаймало 30 хвилин на аркуші, але це було зроблено.
Метт Паркер,

Відповіді:


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)

Це було саме те, що я шукав. Легкий у використанні та злий швидко. Це мій новий BFF. Дякуємо за підказку @Dirk E!

До речі, я не хочу брати під увагу цю відповідь від Дірка Е, тому, якщо він опублікує відповідь, прийміть її, а не мою!


Я спробував стільки методів, щоб прочитати великий файл .xslx, але, здавалося, у мене нічого не вийшло. Я отримував помилку, коли використовував функцію Шауна Вілера на github, і не міг зрозуміти, як використовувати команду perl у gdata для мого комп'ютера. 'openxlsx "для мене такий рятувальник життя. Дякую @Dirk Eddelbuettel та Орвілу Джексону.
Нася Джаффрі,

Чи знаєте ви ще одне рішення? Я не можу знайти спосіб відкрити файли .xls за допомогою openxlsx
user124123

Ви можете спробувати функцію read.xls у пакеті gdata. Ніколи не використовував його сам, але вартий пострілу.
orville jackson

1
openxlsx - єдина бібліотека, яка працювала для мого файлу excel (70Mo). але мені спочатку довелося конвертувати з .xls в .xlsx
agenis

Недолік OpenXLSX полягає в тому, що він не розпізнає дати. Мені read_excel із пакета readxl здається правильним шляхом.
peer

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

дозволити більше пам'яті, використовуючи "параметри" перед завантаженням будь-якого компонента Java. Потім завантажте бібліотеку XLConnect (вона використовує java).

Це воно. Почніть читати дані за допомогою readWorksheet .... тощо. :)


2
Дякую за підказку. Важливо зазначити: мені довелося видавати це options(java.parameters = "-Xmx2048m")перед випуском, require('rJava')коли я використовував це в R-Studio. На жаль, зараз я отримую нову помилку: "java.lang.OutOfMemoryError: перевищено ліміт накладних витрат у GC", але це певна проблема, я впевнений.
pbnelson

Це працює для мене, але я повинен був переконатися , що мій R версії відповідає моїй версії Java (наприклад , як 64-розрядна версія ), і вказуємо шлях Java правильно: options(java.parameters="-Xmx4g") # increase java memory, Sys.setenv(JAVA_HOME='C:\\Program Files\\Java\\jdk-11.0.2') # for 64-bit version,library(rJava) # check it works
Саймон Woodward

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.

Примітка: Incase 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 в рази швидше за інших
Алі

7

Я знаю, що це питання трохи давнє, але сьогодні є гарне рішення для цього. Це пакет за замовчуванням, коли ви намагаєтесь імпортувати Excel у Rstudio з графічним інтерфейсом, і це добре працює в моїй ситуації.

library(readxl)

data <- read_excel(filename)

5

Як згадувалось у канонічному питанні Excel-> R , нещодавно з’явилася альтернатива виходить із readxlпакету, який, на мою думку, є досить швидким у порівнянні з, наприклад, openxlsxі xlsx.

Тим не менш, існує певна межа розміру електронної таблиці, після якої вам, мабуть, краще просто зберегти річ як .csvта та використовувати fread.


3

У мене також була однакова помилка в обох xlsx::read.xlsxі XLConnect::readWorksheetFromFile. Можливо, ви можете використовувати RODBC::odbcDriverConnectі RODBC::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

Я знайшов цю тему, шукаючи відповідь на те саме питання. Замість того, щоб намагатися зламати xlsx-файл з R, для мене все закінчилося тим, що він перетворив файл у .csv за допомогою python, а потім імпортував файл у R, використовуючи стандартну функцію сканування.

Перевірте: https://github.com/dilshod/xlsx2csv


1
... що є доступним протягом десятиліття у пакеті gdata для R (але з використанням Perl за лаштунками).
Dirk Eddelbuettel

коли я працював над проблемою за допомогою gdata, це було неприпустимо повільно. цей сценарій python надзвичайно швидко перетворює великі файли XLSX
Аарон,

1
Чим ця відповідь відрізняється від пропозиції @ flodel, згаданої в іншій відповіді? IMHO RODBC має мало переваг перед проміжним форматом CSV.
mlt

8
У блоці також є нова дитина: openxlsx, яка використовує лише Rcpp і нічого, крім коду C ++, - і стверджує, що вона дуже швидка. Не впевнений, наскільки це вишукано.
Дірк Еддельбюттель

чому б вам просто не відкрити його в Excel і не експортувати до CSV?
Метте
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.