11

我想在 R 中使用merge多个,做一个完整的外连接。为此,我希望执行以下操作:data.framerow.names

x = as.data.frame(t(data.frame(a=10, b=13, c=14)))
y = as.data.frame(t(data.frame(a=1, b=2)))
z = as.data.frame(t(data.frame(a=3, b=4, c=3, d=11)))
res = Reduce(function(a,b) merge(a,b,by="row.names",all=T), list(x,y,z))

Warning message:
In merge.data.frame(a, b, by = "row.names", all = T) :
  column name ‘Row.names’ is duplicated in the result
> res
  Row.names Row.names V1.x V1.y V1
    1         1         a   10    1 NA
    2         2         b   13    2 NA
    3         3         c   14   NA NA
    4         a      <NA>   NA   NA  3
    5         b      <NA>   NA   NA  4
    6         c      <NA>   NA   NA  3
    7         d      <NA>   NA   NA 11

我希望得到的是:

    V1 V2 V3
  a 10 1  3
  b 13 2  4
  c 14 NA 3
  d NA NA 11
4

3 回答 3

10

以下作品(最多一些最后的列重命名):

res <- Reduce(function(a,b){
        ans <- merge(a,b,by="row.names",all=T)
        row.names(ans) <- ans[,"Row.names"]
        ans[,!names(ans) %in% "Row.names"]
        }, list(x,y,z))

确实:

> res
  V1.x V1.y V1
a   10    1  3
b   13    2  4
c   14   NA  3
d   NA   NA 11

行连接会发生什么情况是在答案中添加了具有原始行名的列,而该列又不包含行名:

> merge(x,y,by="row.names",all=T)
  Row.names V1.x V1.y
1         a   10    1
2         b   13    2
3         c   14   NA

此行为记录在?merge(在值下)

如果匹配涉及行名,则在左侧添加一个名为 Row.names 的额外字符列,并且在所有情况下,结果都具有“自动”行名。

Reduce尝试再次合并时,除非手动清理名称,否则找不到任何匹配项。

于 2013-02-09T00:54:41.970 回答
2

为了连续性,这不是一个干净的解决方案,而是一种解决方法,我使用sapply.

Reduce(function(a,b) merge(a,b,by=0,all=T),
                      sapply(list(x,y,z),rbind))[,-c(1,2)]
   x y.x y.y
1 10   1   3
2 13   2   4
3 14  NA   3
4 NA  NA  11
Warning message:
In merge.data.frame(a, b, by = 0, all = T) :
  column name ‘Row.names’ is duplicated in the result
于 2013-02-09T01:03:54.107 回答
0

出于某种原因,我在使用 Reduce 方面没有取得多大成功。给定一个 data.frames 列表(df.lst)和一个后缀列表(suff.lst)来更改相同列的名称,这是我的解决方案(它是循环,我知道它对于 R 标准来说很难看,但它有效) :

df.merg <- as.data.frame(df.lst[1])
colnames(df.merg)[-1] <- paste(colnames(df.merg)[-1],suff.lst[[1]],sep="")
for (i in 2:length(df.lst)) {
    df.i <- as.data.frame(df.lst[i])
    colnames(df.i)[-1] <- paste(colnames(df.i)[-1],suff.lst[[i]],sep="")
    df.merg <- merge(df.merg, df.i, by.x="",by.y="", all=T)
}
于 2013-12-17T18:48:01.307 回答