La manipulation de java.lang.OutOfMemoryError lors de l'écriture dans Excel à partir de R

La xlsx emballage peut être utilisé pour lire et écrire des feuilles de calcul Excel à partir de R. Malheureusement, même modérée de grandes feuilles de calcul, java.lang.OutOfMemoryError peut se produire. En particulier,

## 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 

(D'autres exceptions sont également possibles mais plus rares.)

Une question semblable a été posée au sujet de cette erreur lors de la lecture des feuilles de calcul.

L'importation d'un gros fichier xlsx dans R?

Le principal avantage de l'utilisation de feuilles de calcul Excel en tant que support de stockage de données de plus de CSV est que vous pouvez stocker plusieurs feuilles d'un même fichier, de sorte que l'on considère ici une liste de trames de données d'être écrit une trame de données par feuille de calcul. Cet exemple de jeu de données contient 40 trames de données, chacune avec deux colonnes jusqu'à 200k lignes. Il est conçu pour être suffisamment grand pour être problématique, mais vous pouvez changer la taille en modifiant n_sheets et 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))

La méthode naturelle de l'écriture de ce fichier est de créer un classeur à l'aide de createWorkbook, puis une boucle sur chaque bloc de données d'appel createSheet et addDataFrame. Enfin du classeur peuvent être écrites dans le fichier à l'aide de saveWorkbook. J'ai ajouté des messages à la boucle pour le rendre plus facile de voir où il tombe.

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

L'exécution de ce en 64 bits sur une machine avec 8 go de RAM, il jette la GC overhead limit exceeded d'erreur lors de l'exécution de addDataFrame pour la première fois.

Comment puis-je écrire de grands ensembles de données de feuilles de calcul Excel à l'aide de xlsx?