我正在使用for循环将多个文件与另一个文件合并:
文件< - list.files("路径",模式=" .TXT",ignore.case = T)
for(i in 1:length(files))
{
data <- fread(files[i], header=T)
# Merge
mydata <- merge(mydata, data, by="ID", all.x=TRUE)
rm(data)
}
&#34; MYDATA&#34;看起来如下(简化):
ID x1 x2
1 2 8
2 5 5
3 4 4
4 6 5
5 5 8
&#34;数据&#34;看起来如下(大约600个文件,总共100GB)。 2(单独)文件的示例。将all all整合为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个文件)。
关于如何尽可能高效地实现这一目标的任何想法都非常赞赏。
答案 0 :(得分:5)
它更适合作为评论,但我还不能发表评论。
rbind而不是合并会不会更好? 这似乎是你想要实现的。
设置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
执行此操作,然后mydata
合并到ID
。
更新评论
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
plyr
将所有数据帧转换为一个数据帧。
不要碰mydata。
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]]
}