【问题标题】:rbind two data.frame preserving row order and row namesrbind 两个 data.frame 保留行顺序和行名
【发布时间】:2013-01-25 19:18:41
【问题描述】:

我有一个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
  • 如果我没听错的话,你想rbind不同列数的数据框在一起。 This question 可能对您有所帮助,尤其是来自 plyr 包的 rbind.fill
  • @Arun Ananda Mahto's answer 负责处理。

标签: r merge dataframe rbind


【解决方案1】:

既然你知道你实际上并没有合并,而只是 rbind-ing,也许这样的事情会起作用。它利用“plyr”中的rbind.fill。要使用它,请指定您想要的data.frames 中的list rbind

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

【讨论】:

    【解决方案2】:

    一种方法是在合并中使用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,按照 OP 对本示例的预期工作。只是一个实验。

    【讨论】:

    • +1。我总是忘记能够合并"row.names"
    • 关于您的编辑,我还必须删除第 141 行 (attr(res, "row.names") &lt;- .set_row_names(nrow(res)))。我提出了一个要点here,可以使用library(devtools); source_gist(4750113); MERGE(x, y, all = TRUE) 加载和运行它,至少部分验证了您的实验。
    • 假设您有第三个 df,z &lt;- 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 解决方案。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 2018-06-06
    相关资源
    最近更新 更多