我有600个.txt
个文件(总共大约250GB)。对于每个文件,我计算一个额外的变量,我需要将其与另一个单独的(较小的)数据集合并。我确实需要所有600个txt
文件中的所有观察值来计算这些变量。
目前,我分别为每个文件计算此变量(合并所有600个文件是不可能的),并且仅将此变量与唯一ID保存在单独的txt
文件中。
问题是我的内存不足。有没有更有效的方法来合并这个?任何建议都非常受欢迎。
我的代码如下(在1个小文件上应用时效果很好):
我为600个文件中的每一个执行以下操作:
计算额外变量
2.子集数据集仅包含我需要的变量和要合并的唯一ID,
3.另存为txt
个文件。
files <- list.files("path", pattern = "*.TXT")
# Loop over files
for (i in 1:length(files))
{
data <- read.table(files[i], header = TRUE)
# Compute extra variables
data$newvar <- (data$v1 * data$v2)
data <- ddply(data, .(v3,v4,v5), transform, newvar2 = sum(newvar))
# Subset data
varstokeep <- c("ID", "newvar2")
data <- data[varstokeep]
# Save data
write.table(data, paste("path[", i, "].txt"), sep = "\t")
rm(data)
}
答案 0 :(得分:2)
#Load libs data.table
library(data.table)
#File list
files <- list.files("path", pattern = "*.TXT")
#Define variables to keep
varstokeep <- c("ID", "newvar2")
# Loop over files
for (i in 1:length(files)){
#Use fread here : very fast, reads straight into a data.table
data <- fread(files[i], header=T, stringsAsFactors=F)
# Compute extra variables, see `?":="`
data[, newvar:=v1*v2]
# Sum of all values on "newvar" per shop(v3), per category (v4), per week
data[, newvar2:=sum(newvar), .(v3, v4, v5)]
# index of variables not to keep
vartodrop <- which(!names(data)%in%varstokeep)
# Subset data: again, efficiently with ":="
set(data, i=NULL, j=vartodrop, value=NULL)
# Save data
write.table(data, paste("path[", i, "].txt"), sep = "\t")
rm(data)
}
在此解决方案中,不会生成不必要的数据副本。这消除了使用data.frames
的任何开销,这些开销在每次修改期间被复制,可能需要比您更多的内存。请注意<-
的稀缺性。看看这是否足以解决你的mem问题。
答案 1 :(得分:0)
我认为@Shekeine是正确的,您需要重新考虑您的数据方法,但是现在一个快速而肮脏的解决方案可能是在您删除当前后使用gc()
强制进行垃圾回收从您的环境中迭代data
。
...
# Save data
write.table(data, paste("path[", i, "].txt"), sep = "\t")
rm(data)
gc()
}
注意:无论如何,R通常会自行清除,但这可能足以处理您的文件。认为这是一个黑客;这不是可以依赖的东西!