rbind两个数据框,保留行顺序和行名。

12

我有一组data.frame对象,我想将它们逐行附加在一起,即使用merge(..., all=T)。然而,merge似乎会删除我需要保留的行名称。有什么建议吗?示例:

x = data.frame(a=1:2, b=2:3, c=3:4, d=4:5, row.names=c("row_1", "another_row1"))
y = data.frame(a=c(10,20), b=c(20,30), c=c(30,40), row.names=c("row_2", "another_row2"))
> merge(x, y, all=T, sort=F)
     a  b  c  d
  1  1  2  3  4
  2  2  3  4  5
  3 10 20 30 NA
  4 20 30 40 NA

可能是: z <- merge(x, y, all=T, sort=F); rownames(z) <- c(rownames(x), rownames(y)) - Arnaud A
3
如果我理解正确,您想将不同列数的数据框合并在一起。这个问题可能会对您有所帮助,特别是plyr包中的rbind.fill函数。 - Blue Magister
@Arun Ananda Mahto的回答 已经解决了这个问题。 - Blue Magister
2个回答

16

既然您知道实际上不是合并而只是 rbind-ing,也许像这样做会起作用。它利用了 "plyr" 中的 rbind.fill。要使用它,请指定您想要 rbinddata.frames 的 list

RBIND <- function(datalist) {
  require(plyr)
  temp <- rbind.fill(datalist)
  rownames(temp) <- unlist(lapply(datalist, row.names))
  temp
}
RBIND(list(x, y))
#               a  b  c  d
# row_1         1  2  3  4
# another_row1  2  3  4  5
# row_2        10 20 30 NA
# another_row2 20 30 40 NA

11

一种方法是在合并时使用row.names,这样您就可以将其作为附加列获取。

> merge(x, y, by=c("row.names", "a","b","c"), all.x=T, all.y=T, sort=F)

#      Row.names  a  b  c  d
# 1        row_1  1  2  3  4
# 2 another_row1  2  3  4  5
# 3        row_2 10 20 30 NA
# 4 another_row2 20 30 40 NA

编辑:通过查看getS3method('merge', 'data.frame')merge函数,可以清楚地看到row.names被设置为NULL(代码很长,所以我不会在这里粘贴)。

# Commenting 
# Lines 63 and 64
row.names(x) <- NULL
row.names(y) <- NULL

# and 
# Line 141 (thanks Ananda for pointing out)
attr(res, "row.names") <- .set_row_names(nrow(res))

创建一个新的函数,比如说MERGE,可以像操作员在这个例子中期望的那样工作。只是一次试验。


+1. 我总是忘记能够合并“row.names”。 - A5C1D2H2I1M1N2O1R2T1
关于你的修改,我也不得不删除第141行(attr(res, "row.names") <- .set_row_names(nrow(res)))。我在这里放了一个Gist,可以使用library(devtools); source_gist(4750113); MERGE(x, y, all = TRUE)加载和运行,至少在某种程度上验证了你的实验。 - A5C1D2H2I1M1N2O1R2T1
假设您有第三个数据框,z <- data.frame(a = c(11, 21), b = c(22, 32), d = c(33, 43), row.names = c("row_3", "another_row3"))。我们如何让常规的 merge 函数工作(也许使用 Reduce,甚至手动)?MERGE 函数与 Reduce(function(x, y) MERGE(x, y, all = TRUE, sort = FALSE), list(x, y, z)) 配合使用时可以正常工作(或多或少--列顺序会改变),而 RBIND(list(x, y, z)) 也可以解决问题。但我无法想出一个未经修改的基本 merge 解决方案。有什么想法吗? - A5C1D2H2I1M1N2O1R2T1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接