【问题标题】:Merge in loop R在循环 R 中合并
【发布时间】:2016-06-18 08:30:35
【问题描述】:

我正在使用 for 循环将多个文件与另一个文件合并:

文件

for(i in 1:length(files))
{
  data <- fread(files[i], header=T)

  # Merge
  mydata <- merge(mydata, data, by="ID", all.x=TRUE)

  rm(data)
}

“mydata”如下所示(简化):

ID  x1  x2
1   2   8
2   5   5
3   4   4
4   6   5
5   5   8

“数据”如下所示(大约 600 个文件,总共 100GB)。 2 个(单独的)文件的示例。将 all in 1 集成是不可能的(太大):

ID  x3
1   8
2   4

ID  x3
3   4
4   5
5   1

当我运行我的代码时,我得到以下数据集:

ID  x1  x2  x3.x    x3.y
1   2   8   8       NA
2   5   5   4       NA
3   4   4   NA      4
4   6   5   NA      5
5   5   8   NA      1

我想得到的是:

ID  x1  x2  x3
1   2   8   8
2   5   5   4
3   4   4   4
4   6   5   5
5   5   8   1

ID 是唯一的(从不重复超过 600 个文件)。

任何关于如何尽可能有效地实现这一目标的想法都非常感谢。

【问题讨论】:

  • 您是否尝试将所有文​​本文件合并为单个文本文件?如果 ID 是唯一的,为什么不使用 rbindcbind 来加入它们而不是合并?
  • 我不认为有一个函数可以按照您想要的方式为您的数据结构“合并”。我们可能不得不写一个。您的data 文件不一定总是只包含“x3”列,对吧?
  • 数据始终完全相同,1 列“ID”,1 列“x3”。我在单独的数据文件中只有比 mydata 更多的 ID

标签: r for-loop merge


【解决方案1】:

它更适合作为评论,但我还不能评论。

用rbind 代替merge 不是更好吗? 这似乎是您想要完成的。

设置fill 参数TRUE 来处理不同的列号:

asd <- data.table(x1 = c(1, 2), x2 = c(4, 5))
a <- data.table(x2 = 5)
rbind(asd, a, fill = TRUE)

   x1 x2
1:  1  4
2:  2  5
3: NA  5

使用data 执行此操作,然后通过ID 合并到mydata

评论更新

files <- list.files("path", pattern=".TXT", ignore.case=T)

ff <- function(input){
  data <- fread(input) 
}

a <- lapply(files, ff)
library(plyr)
binded.data <- ldply(a, function(x) rbind(x, fill = TRUE))

因此,这将创建一个函数来读取文件并将其推送到 lapply,因此您将获得一个包含所有 data 文件的列表,每个文件都在其自己的数据帧中。

使用 ldply from plyr 将所有数据帧合并到一个数据帧中。

暂时不要碰我的数据。

binded.data <- data.table(binded.data, key = ID)

根据您的mydata,您将执行不同的merge 命令。 看: https://rstudio-pubs-static.s3.amazonaws.com/52230_5ae0d25125b544caab32f75f0360e775.html

更新 2

files <- list.files("path", pattern=".TXT", ignore.case=T)

ff <- function(input){
data <- fread(input)
# This keeps only the rows of 'data' whose ID matches ID of 'mydata'
data <- data[ID %in% mydata[, ID]]
}

a <- lapply(files, ff)
library(plyr)
binded.data <- ldply(a, function(x) rbind(x, fill = TRUE))

更新 3

您可以添加cat 来查看函数正在读取的文件。因此,您可以查看哪个文件内存不足。这将为您指明一次可以读取多少个文件的方向。

  ff <- function(input){
# This will print name of the file it is reading now
cat(input, "\n")
data <- fread(input)
# This keeps only the rows of 'data' whose ID matches ID of 'mydata'
data <- data[ID %in% mydata[, ID]]
}

【讨论】:

  • 对不起,我不确定我是否理解正确。你的意思是 rbind 所有单独的“数据”?我在循环中尝试了 rbind mydata 和 data,但这不起作用
  • 它适用于示例,但不适用于我的数据。无法为我的所有“数据”文件 (=100GB) 获取 1 个数据表,我遇到了内存问题。是否可以按顺序合并(因此对于每个“数据”与“mydata”),因为 mydata 要小得多。或仅在此 bind.data 中添加与“mydata”匹配的观察结果
  • 你能创建列表吗? “a
  • 我也遇到了“a
  • 我有一种感觉,即使是最终合并的文件也会太大而无法处理:/您现在可以尝试将“文件”分成更小的块。所以不是一次全部 600 个文件,而是 6 次运行 100 个文件?
猜你喜欢
  • 2018-10-27
  • 2016-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 2011-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多