使用约束合并R中的多个文本文件

时间:2014-06-18 07:59:20

标签: r

我有10个包含1000行的文本文件。

实施例: 第一档:

V1  V2
1   2
2   3
10 20
1   4    
.....

第二档:

V1  V2
1   2
8   10
.....

我想要的是一个包含12列的最终文件。前两列表示关系,后两列表示不同的文件(如果该对存在则表示为1,如果不存在则表示0) 例如:

最终档案:

V1  V2  V3  V4  V5  V6  V7  V8  V9  V10  V11  V12
1   2   1   1   0   0   1    0   1   1    0     1
2   3   1   0   1   1   0    0   0   1    1     0

现在,我所做的是对每个文件进行排序,以便所有以1作为第一个数字的对出现在顶部,然后是其他数字,即

对于特定文件,我这样做了,

V1   V2

1     2
1     3 
1     10
1     5
2     10 
2     15
.......

然后,我尝试使用merge命令,但是,我知道它不是正确的命令。我无法想到其他方法。

3 个答案:

答案 0 :(得分:1)

这是一种方法。我假设您已将文件读入list data.frames,例如与L <- lapply(filenames, read.table)。我将在下面模拟这个L

# Create dummy data
L <- replicate(5, expand.grid(1:10, 1:10)[sample(100, 10), ], simplify=FALSE)

# Add a column to each data.frame in L. 
# This will indicate presence of the pair when we merge.
L <- lapply(seq_along(L), function(i) { 
  L[[i]][, paste0('DF', i)] <-  1
  L[[i]] 
})

# Merge all the things 
# (hat-tip to @Charles - https://stackoverflow.com/a/8097519/489704)
L.merged <- Reduce(function(...) merge(..., all=T), L)

head(L.merged)

#   Var1 Var2 DF1 DF2 DF3 DF4 DF5
# 1    1    2  NA  NA  NA   1  NA
# 2    1    5   1  NA  NA  NA   1
# 3    1    9  NA  NA  NA   1  NA
# 4    1   10  NA  NA   1   1  NA
# 5    2    5  NA  NA   1  NA  NA
# 6    2    6  NA   1  NA   1  NA

如果您愿意,可以轻松将NA转换为0,例如用:

L.merged[is.na(L.merged)] <- 0

相关帖子: Merge multiple data frames in a list simultaneously

答案 1 :(得分:1)

为简单起见,假设您只有四个带有这些数字的文件:

m <- cbind(1, c(1,2,3,5), c(2,3,4,6))
m <- rbind(m, cbind(2, c(2,3,5), c(3,6,1)))
m <- rbind(m, cbind(3, c(1,2), c(4,6)))
m <- rbind(m, cbind(4, c(2,2,4), c(4,6,5)))
colnames(m) <- c("file", "val1", "val2")
m
      file val1 val2
[1,]     1    1    2
[2,]     1    2    3
[3,]     1    3    4
[4,]     1    5    6
[5,]     2    2    3
[6,]     2    3    6
[7,]     2    5    1
[8,]     3    1    4
[9,]     3    2    6
[10,]    4    2    4
[11,]    4    2    6
[12,]    4    4    5

然后,您可以获得每个文件中每对计数的表格:

vals <- apply(m[,2:3], 1, paste, collapse = "")
m <- cbind(m[,1], vals)
tab <- table(m[,1], m[,2])
tab
    12 14 23 24 26 34 36 45 51 56
  1  1  0  1  0  0  1  0  0  0  1
  2  0  0  1  0  0  0  1  0  1  0
  3  0  1  0  0  1  0  0  0  0  0
  4  0  0  0  1  1  0  0  1  0  0

现在您可以格式化输出

res <- cbind(colnames(tab), apply(tab, 2, paste, collapse = ""))
res <- as.vector(apply(res, 1, paste, collapse = " "))
res
 [1] "12 1000" "14 0010" "23 1100" "24 0001" "26 0011" "34 1000" "36 0100"
 [8] "45 0001" "51 0100" "56 1000"

cat(paste(res, collapse = "\n"))
12 1000
14 0010
23 1100
24 0001
26 0011
34 1000
36 0100
45 0001
51 0100
56 1000

答案 2 :(得分:0)

试试这个例子:

#dummy files
file1 <- read.table(text="V1  V2
1   2
2   3
10 20
1   4   ",header=TRUE)
file2 <- read.table(text="
V1  V2
1   2
8   10",header=TRUE)

#make list of files - this can be done by lapply(list.files(),read.table)
all_files <- list(file1,file2)

#get unique pairs
unique_pairs <- unique(do.call(rbind,all_files))
#add new pair that is not in file1 and file2
unique_pairs <- rbind(unique_pairs,c(33,22))

#loop through pairs and files
result <- sapply(1:nrow(unique_pairs),
                 function(x)
                   sapply(all_files,function(myfile){
                     #merge pair with file then check number of rows
                     d <- merge(myfile,unique_pairs[x,,drop=FALSE])
                     ifelse(nrow(d)==0,0,1)
                   }))

#output
cbind(unique_pairs,t(result))
# V1 V2 1 2
# 1   1  2 1 1
# 2   2  3 1 0
# 3  10 20 1 0
# 4   1  4 1 0
# 6   8 10 0 1
# 61 33 22 0 0