我需要對非常大的csv文件(c.8.5GB)進行一些相對簡單的更改。我最初嘗試使用各種閱讀器函數:read.csv,readr :: read.csv,data.table :: fread。但是:它們全部用完內存。流處理R中的大csv文件
我想我需要使用流處理方法,而不是;讀一個塊,更新它,寫下來,重複。我發現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'。它允許從文本文件中chunkwise讀取,特別有趣的是,使用dplyr進行chunkwise處理。沒有小插曲,但介紹https://github.com/edwindj/chunked/使用 我打算自己嘗試,但沒有找到時間! –