非常に大きなcsvファイル(c.8.5GB)に対して比較的簡単な変更を加える必要があります。最初はさまざまなリーダー関数read.csv、readr :: read.csv、data.table :: freadを使って試してみました。しかし、それらはすべてメモリ不足です。大規模なcsvファイルをRで処理するストリーム
代わりにストリーム処理のアプローチを使用する必要があると思います。チャンクを読んだり、更新したり、書き込んだり、繰り返したりする。私は右の行にあるthis answerを見つけました。しかし、私はループを終了する方法はありません(私はRに比較的新しいです)。
だから私は2つの質問があります:
- をwhileループの作業を行うための正しい方法は何ですか?
- 「より良い」という定義にはより良い方法がありますか?例えばdplyr &パイプを使用してこれを行う方法がいくつかありますか?
現在のコードは次のように任意のポインタのための
src_fname <- "testdata/model_input.csv"
tgt_fname <- "testdata/model_output.csv"
#Changes needed in file: rebase identifiers, set another col to constant value
rebase_data <- function(data, offset) {
data$'Unique Member ID' <- data$'Unique Member ID' - offset
data$'Client Name' <- "TestClient2"
return(data)
}
CHUNK_SIZE <- 1000
src_conn = file(src_fname, "r")
data <- read.csv(src_conn, nrows = CHUNK_SIZE, check.names=FALSE)
cols <- colnames(data)
offset <- data$'Unique Member ID'[1] - 1
data <- rebase_data(data, offset)
#1st time through, write the headers
tgt_conn = file(tgt_fname, "w")
write.csv(data,tgt_conn, row.names=FALSE)
#loop over remaining data
end = FALSE
while(end == FALSE) {
data <- read.csv(src_conn, nrows = CHUNK_SIZE, check.names=FALSE, col.names = cols)
data <- rebase_data(data, offset)
#write.csv doesn't support col.names=FALSE; so use write.table which does
write.table(data, tgt_conn, row.names=FALSE, col.names=FALSE, sep=",")
# ??? How to test for EOF and set end = TRUE if so ???
# This doesn't work, presumably because nrow() != CHUNK_SIZE on final loop?
if (nrow(data) < CHUNK_SIZE) {
end <- TRUE
}
}
close(src_conn)
close(tgt_conn)
感謝を。
チェックアウトCRANのパッケージ 'chunked'何のパッケージとのビネットが、標準的な使用法は、githubの上で説明されていないことを
注意。これは、テキストファイルからのチャンクワイズ読み込み、特に興味深い、dplyrでのチャンクワイズ処理を可能にします。ビネットはありませんが、https://github.com/edwindj/chunked/の使用方法の紹介 私は自分で試してみることを意図しましたが、時間を見つけられませんでした! –