이 xlsx
패키지는 R에서 Excel 스프레드 시트를 읽고 쓰는 데 사용할 수 있습니다. 안타깝게도 중간 크기의 스프레드 시트에서도 java.lang.OutOfMemoryError
발생할 수 있습니다. 특히,
.jcall ( “RJavaTools”, “Ljava / lang / Object;”, “invokeMethod”, cl, :
java.lang.OutOfMemoryError : Java 힙 공간에 오류가 있습니다..jcall ( “RJavaTools”, “Ljava / lang / Object;”, “newInstance”, .jfindClass (class), :
java.lang.OutOfMemoryError : GC 오버 헤드 제한 초과
(기타 관련 예외도 가능하지만 더 드뭅니다.)
스프레드 시트를 읽을 때이 오류와 관련하여 유사한 질문이 제기되었습니다.
CSV보다 Excel 스프레드 시트를 데이터 저장 매체로 사용할 때의 주요 이점은 동일한 파일에 여러 시트를 저장할 수 있다는 것입니다. 따라서 여기서는 워크 시트 당 하나의 데이터 프레임을 작성하는 데이터 프레임 목록을 고려합니다. 이 예제 데이터 세트에는 40 개의 데이터 프레임이 포함되어 있으며 각 프레임에는 최대 200,000 개의 행이있는 두 개의 열이 있습니다. 문제가 될 수있는 충분히 큰 수 있도록 설계되어 있지만 변경하여 크기를 변경할 수 있습니다 n_sheets
및 n_rows
.
library(xlsx)
set.seed(19790801)
n_sheets <- 40
the_data <- replicate(
n_sheets,
{
n_rows <- sample(2e5, 1)
data.frame(
x = runif(n_rows),
y = sample(letters, n_rows, replace = TRUE)
)
},
simplify = FALSE
)
names(the_data) <- paste("Sheet", seq_len(n_sheets))
이 파일을 기록하는 자연있어서 사용 통합 문서를 생성하는 createWorkbook
각각의 데이터 프레임을 통해 호출 후, 루프 createSheet
와 addDataFrame
. 마지막으로 통합 문서는 saveWorkbook
. 루프가 어디로 넘어가는지 쉽게 볼 수 있도록 메시지를 루프에 추가했습니다.
wb <- createWorkbook()
for(i in seq_along(the_data))
{
message("Creating sheet", i)
sheet <- createSheet(wb, sheetName = names(the_data)[i])
message("Adding data frame", i)
addDataFrame(the_data[[i]], sheet)
}
saveWorkbook(wb, "test.xlsx")
8GB RAM이있는 시스템에서 64 비트로 GC overhead limit exceeded
실행 addDataFrame
하면 처음 실행하는 동안 오류가 발생 합니다.
을 사용하여 대용량 데이터 세트를 Excel 스프레드 시트에 어떻게 작성 xlsx
합니까?
답변
이것은 알려진 문제입니다.
http://code.google.com/p/rexcel/issues/detail?id=33
해결되지 않은 동안 문제 페이지 는 패키지가로드 되기 전에 옵션 을 설정하여 힙 크기를 늘려야한다고 제안하는 Gabor Grothendieck 의 솔루션 에 연결됩니다 . ( 의 종속성입니다 .)java.parameters
rJava
rJava
xlsx
options(java.parameters = "-Xmx1000m")
값 1000
은 Java 힙을 허용하는 RAM의 MB 수입니다. 원하는 값으로 바꿀 수 있습니다. 이것에 대한 나의 실험은 더 큰 값이 더 낫다는 것을 시사하며 전체 RAM 권한을 행복하게 사용할 수 있습니다. 예를 들어 다음을 사용하여 최상의 결과를 얻었습니다.
options(java.parameters = "-Xmx8000m")
8GB RAM이있는 컴퓨터에서.
루프를 반복 할 때마다 가비지 콜렉션을 요청하여 추가 개선을 얻을 수 있습니다. @gjabel에서 언급했듯이 R 가비지 수집은 gc()
. Java System.gc()
메소드 를 호출하는 Java 가비지 콜렉션 함수를 정의 할 수 있습니다 .
jgc <- function()
{
.jcall("java/lang/System", method = "gc")
}
그런 다음 루프를 다음과 같이 업데이트 할 수 있습니다.
for(i in seq_along(the_data))
{
gc()
jgc()
message("Creating sheet", i)
sheet <- createSheet(wb, sheetName = names(the_data)[i])
message("Adding data frame", i)
addDataFrame(the_data[[i]], sheet)
}
이 두 코드 수정을 통해 코드는 i = 29
오류가 발생하기 전까지 실행되었습니다 .
실패한 한 가지 기술 write.xlsx2
은 각 반복에서 내용을 파일에 쓰는 데 사용 하는 것입니다. 이것은 다른 코드보다 느 렸고 10 번째 반복에서 넘어졌습니다 (하지만 적어도 내용의 일부가 파일에 기록되었습니다).
for(i in seq_along(the_data))
{
message("Writing sheet", i)
write.xlsx2(
the_data[[i]],
"test.xlsx",
sheetName = names(the_data)[i],
append = i > 1
)
}
답변
@ richie-cotton 답변을 바탕으로 기능에 추가 하면 CPU 사용량이 낮다 gc()
는 것을 알았습니다 jgc
.
jgc <- function()
{
gc()
.jcall("java/lang/System", method = "gc")
}
내 이전 for
루프는 여전히 원래 jgc
기능으로 어려움을 겪었 지만 추가 명령을 사용하면 더 이상 GC overhead limit exceeded
오류 메시지가 표시 되지 않습니다 .
답변
행 단위로 쓰는 경우 루프 내에서 gc ()를 사용할 수도 있습니다. gc ()는 가비지 콜렉션을 의미합니다. gc ()는 메모리 문제의 모든 경우에 사용할 수 있습니다.
답변
위 오류에 대한 해결 방법 : 아래에 언급 된 r 코드를 사용하십시오.
detach(package:xlsx)
detach(package:XLConnect)
library(openxlsx)
그리고 파일을 다시 가져 오면 저에게 작동하므로 오류가 발생하지 않습니다.
답변
읽는 대신 write.xlsx ()에 문제가 있었지만 실수로 32 비트 R을 실행했음을 깨달았습니다. 64 비트로 바꾸면 문제가 해결되었습니다.