[解決済み] RからExcelへの書き込み時のjava.lang.OutOfMemoryErrorの処理について
質問
質問
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のスプレッドシートをデータ保存媒体として使用する主な利点は、同じファイルに複数のシートを保存できることなので、ここではデータフレームのリストは、1つのワークシートに1つのデータフレームを書き込むと考えます。 このデータセットの例では、40個のデータフレームがあり、それぞれ2列で最大200k行のデータフレームとなっています。 問題にならない程度の大きさに設計されていますが、サイズを変更するために
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-bit でこれを実行すると、以下のようになります。
GC overhead limit exceeded
を実行中にエラーが発生します。
addDataFrame
を初めて実行したときに発生します。
大きなデータセットをExcelスプレッドシートに書き込むには、どのように
xlsx
?
どのように解決するのですか?
これは既知の問題です。 http://code.google.com/p/rexcel/issues/detail?id=33
未解決のまま、問題ページ
は解決策にリンクしています。
によって
ガボール・グローセンディーク
がヒープサイズを大きくすることを示唆しています。
java.parameters
オプションの前に
rJava
パッケージがロードされます。 (
rJava
の依存関係は
xlsx
.)
options(java.parameters = "-Xmx1000m")
値
1000
はJavaヒープのために許容されるRAMのメガバイトの数です; それはあなたが望む任意の値で置き換えることができます。 私の実験によると、より大きな値を指定した方がよく、RAM の権利を完全に使用することができます。 たとえば、私は次のように使って最良の結果を得ました。
options(java.parameters = "-Xmx8000m")
を8GB RAMのマシンで実行します。
ループの各反復でガベージコレクションを要求することで、さらなる改善を得ることができます。 gjabel が指摘したように、R ガーベッジコレクションを実行するには
gc()
. Java のガベージコレクション関数を定義し、その関数を呼び出すことで Java の
System.gc()
メソッドを呼び出します。
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
)
}
関連
-
R 描画エラー plot.new() : 図形の余白が大きすぎる
-
二項演算子への非数値引数を報告するR言語エラー
-
R言語ダウンロード機能 download.fileとダウンロード解析
-
[解決済み] Rで文字列から文字を削除する
-
[解決済み] Rの代入演算子"="と"<-"の違いは何ですか?
-
[解決済み] コマンドラインからRスクリプトを実行する
-
[解決済み] Rでロードされているパッケージのバージョンを調べるには?
-
[解決済み] ベクトル中のxの値を持つ要素の個数を数える
-
[解決済み] ベクトル中のある要素のインデックスを求めるR関数はありますか?
-
[解決済み】Rスクリプトで警告をグローバルに抑制する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
R言語のエラーメッセージと関連する解決策
-
R plot.new() のエラー : 図形の余白が大きすぎる
-
DEG解析で'row.names'に重複した名前を付けられない場合の解決法
-
R言語における共通関数
-
[解決済み] "エラーです。Rでテーマの書式を保存する際に「Don't know how to add RHS to the theme object」(テーマオブジェクトにRHSを追加する方法がわかりません)と表示されます。
-
[解決済み] 特定のサイズのプロットウィンドウを作成する
-
[解決済み] require()とlibrary()の違いは何ですか?
-
[解決済み】私のggplot2構文が賢明であるときに、R CMDチェック「no visible binding for global variable」注記を処理するにはどうすればよいですか?
-
[解決済み] データフレームのカラムのデータ型を決定する
-
[解決済み] テーブルをデータフレームに変換する方法