write with support script readxl read namespace manipulate library for failed error r xlsx

with - write xlsx r script



Manejo de java.lang.OutOfMemoryError al escribir en Excel desde R (4)

Este es un problema conocido: http://code.google.com/p/rexcel/issues/detail?id=33

Mientras no se resuelve, la página de problemas se vincula a una solución de Gabor Grothendieck que sugiere que el tamaño del montón debe aumentarse estableciendo la opción java.parameters antes de que se rJava paquete rJava . ( rJava es una dependencia de xlsx ).

options(java.parameters = "-Xmx1000m")

El valor 1000 es el número de megabytes de RAM para permitir el almacenamiento dinámico de Java; puede ser reemplazado con cualquier valor que desee. Mis experimentos con esto sugieren que los valores más grandes son mejores y que puede usar su derecho RAM completo. Por ejemplo, obtuve los mejores resultados usando:

options(java.parameters = "-Xmx8000m")

en la máquina con 8GB de RAM.

Se puede obtener una mejora adicional solicitando una recolección de basura en cada iteración del ciclo. Como señaló @gjabel, la recolección de basura R se puede realizar utilizando gc() . Podemos definir una función de recolección de basura de Java que llama al System.gc() Java System.gc() :

jgc <- function() { .jcall("java/lang/System", method = "gc") }

Luego, el ciclo se puede actualizar a:

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) }

Con ambas correcciones de código, el código corrió tan lejos como i = 29 antes de arrojar un error.

Una técnica que probé sin éxito fue usar write.xlsx2 para escribir los contenidos en el archivo en cada iteración. Esto fue más lento que el otro código, y se cayó en la décima iteración (pero al menos parte del contenido se escribió en el archivo).

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 ) }

El paquete xlsx se puede usar para leer y escribir hojas de cálculo de Excel desde R. Desafortunadamente, incluso para hojas de cálculo moderadamente grandes, java.lang.OutOfMemoryError puede ocurrir. En particular,

## Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl, : ## java.lang.OutOfMemoryError: Java heap space ## Error in .jcall("RJavaTools", "Ljava/lang/Object;", "newInstance", .jfindClass(class), : ## java.lang.OutOfMemoryError: GC overhead limit exceeded

(Otras excepciones relacionadas también son posibles pero menos frecuentes).

Se hizo una pregunta similar con respecto a este error al leer hojas de cálculo.

Importar un gran archivo xlsx en R?

La principal ventaja de utilizar hojas de cálculo de Excel como medio de almacenamiento de datos a través de CSV es que puede almacenar varias hojas en el mismo archivo, por lo que consideramos que una lista de marcos de datos debe escribirse un marco de datos por hoja de trabajo. Este conjunto de datos de ejemplo contiene 40 marcos de datos, cada uno con dos columnas de hasta 200k filas. Está diseñado para ser lo suficientemente grande como para ser problemático, pero puede cambiar el tamaño alterando n_sheets y 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))

El método natural de escribir esto en un archivo es crear un libro de trabajo usando createWorkbook , luego recorrer cada frame de datos llamando a createSheet y addDataFrame . Finalmente, el libro de trabajo se puede escribir en un archivo usando saveWorkbook . He agregado mensajes al ciclo para que sea más fácil ver dónde se cae.

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")

Al ejecutar esto en 64 bits en una máquina con 8 GB de RAM, arroja el error de GC overhead limit exceeded del GC overhead limit exceeded al ejecutar addDataFrame por primera vez.

¿Cómo escribo grandes conjuntos de datos en hojas de cálculo Excel usando xlsx ?


Sobre la base de la respuesta de @ richie-cotton, encontré que agregar gc() a la función jgc mantuvo bajo el uso de la CPU.

jgc <- function() { gc() .jcall("java/lang/System", method = "gc") }

Mi bucle for anterior todavía luchó con la función jgc original, pero con un comando adicional, ya no jgc el jgc mensaje de error GC overhead limit exceeded .


Solución para el error anterior: utilice el código r mencionado a continuación:

separar (paquete: xlsx) separar (paquete: XLConnect) biblioteca (openxlsx)

Y trate de importar el archivo nuevamente y no obtendrá ningún error ya que me funciona.


También puede usar gc () dentro del bucle si está escribiendo fila por fila. gc () representa recolección de basura. gc () se puede usar en cualquier caso de problema de memoria.