代码之家  ›  专栏  ›  技术社区  ›  jay.sf

如何按列名合并表对象?

  •  0
  • jay.sf  · 技术社区  · 5 年前

    我们可以按列名合并两个数据帧 merge() .

    d1 <- data.frame(a=9, b=7)
    d2 <- data.frame(a=6, b=5, c=5)
    
    merge(d1, d2, all=TRUE)
    #   a b  c
    # 1 6 5  5
    # 2 9 7 NA
    

    但我在处理桌上物品时遇到了意想不到的困难。

    t1 <- table(mtcars[1:16, 10])
    t2 <- table(mtcars[-(1:16), 10])
    

    到目前为止,我的尝试失败了:

    # fails
    merge(t1, t2, all=TRUE)
    merge(t(t1), t(t2), all=TRUE)
    merge(as.data.frame(t1), as.data.frame(t2), all=TRUE)
    rbind(t1, t2)
    data.table::rbindlist(t1, t2)
    Reduce(function(x, y) 
      merge(x, y, all=TRUE, by=intersect(names(x), names(y))), list(t1, t2))
    

    这一个可行,但太笨拙了:

    tmp <- merge(t(as.data.frame(t1)), t(as.data.frame(t2)), all=TRUE)
    names(tmp) <- unlist(tmp[1, ])
    tmp <- `rownames<-`(tmp[-1, ], NULL)
    tmp[] <- lapply(tmp, as.numeric)
    tmp
    

    预期输出:

    #   3 4  5
    # 1 9 7 NA
    # 2 6 5  5 
    

    在基R中,我们如何有效地按列名合并表对象以获得data.frame?

    注: 我可能在问一个副本,但所谓的“表”解决方案实际上总是与“data.frame”问题相关联。

    1 回复  |  直到 5 年前
        1
  •  0
  •   clmarquart    5 年前

    使用所提供的每个表的唯一名称,我们可以使用这些名称从表中对每个名称进行子集。这个函数 应该 扩展以使用任意数量的表,但我只使用您的示例数据对其进行了测试

    merge.tables <- function(...) {
      tables = list(...)
      table.names = unique(unlist(sapply(tables, names)))
      merged = sapply(table.names, function(nm) { 
        sapply(tables, function(tbl) tbl[nm])
      })
      row.names(merged) = 1:nrow(merged)
      merged
    }
    merge.tables(t1, t2)