以块为单位读取大型CSV并转换为R中的RDS

whitzsjs  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(331)

我有一个20GB的CSV文件,我想在R中将其转换为RDS文件。但是,原始文件太大,无法处理(有64GB RAM的电脑告诉我需要分配80. 9GB,这超过了它的内存容量)。因此,我想知道,我是否以及如何能够以块的形式读取CSV,将每个数据块转换为单独的RDS文件,然后将它们合并在一起?这会产生与直接将CSV文件转换为RDS文件相同的结果吗?
我对R很陌生,不幸的是找不到我问题的任何答案。
下面是我目前使用的代码。

library(Matrix)
library(data.table)

b <- fread('dtm.csv')
b_matx<- as.matrix(b)
dtm_b <- Matrix(b_matx, sparse = TRUE)

saveRDS(dtm_b, "dtm.rds")
gcuhipw9

gcuhipw91#

看看这是否有效。
它使用fread一次读取一列。默认情况下,fread创建一个 Dataframe ;然而,这些使用外部指针,这可能是个问题,因此我们使用data.table=FALSE参数。在阅读一列后,它立即将其作为RDS文件写回。在所有列都作为RDS文件写回后,它读取RDS文件,并将最终的RDS文件写回,该文件将它们组合在一起。我们使用末尾注解中的6行输入作为示例。
如果带有select=fread仍然占用太多内存,请使用xsv实用程序(不是R程序)确保只读取感兴趣的列。可以为各种平台here下载xsv,然后使用注解掉的行而不是它后面的行。(出于相同目的,也可以适当地使用cutsedawk。)
您也可以尝试在代码行中穿插gc()来触发垃圾回收。
同时尝试将最后一行中的as.data.frame替换为setDT

library(data.table)

File <- "BOD.csv"

freadDF <- function(..., data.table = FALSE) fread(..., data.table = data.table)
L <- as.list(freadDF(File, nrows = 0))
nms <- names(L)
fmt <- "xsv select %s %s"
# for(nm in nms) saveRDS(freadDF(cmd = sprintf(fmt, nm, File))[[1]], paste0(nm, ".rds"))
for(nm in nms) saveRDS(freadDF(File, select = nm)[[1]],  paste0(nm, ".rds"))

for(nm in names(L)) L[[nm]] <- readRDS(paste0(nm, ".rds"))
saveRDS(as.data.frame(L), sub(".csv$", ".rds", File))

注意

write.csv(BOD, "BOD.csv", quote = FALSE, row.names = FALSE)

相关问题