如何在R中有效地存储和合并变量?

时间:2016-02-26 12:36:11

标签: r for-loop memory merge

我有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)
}

2 个答案:

答案 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通常会自行清除,但这可能足以处理您的文件。认为这是一个黑客;这不是可以依赖的东西!