【问题标题】:Merge by column name R按列名 R 合并
【发布时间】:2013-03-24 18:55:25
【问题描述】:

我有

a <- matrix(c(1,3,4,2,2,6,3,1,6), nrow = 3, ncol=3, byrow=TRUE, dimnames = list(NULL, c("Apples", "Pears", "Oranges")))

  Pears Apples Oranges
1     1      3       4
2     2      2       6
3     3      1       6

b <- matrix(c(1,3,2,6,3,6), nrow = 3, ncol=2, byrow=TRUE, dimnames = list(NULL, c( "Pears", "Oranges")))

  Pears Oranges
1     1       4
2     2       6
3     3       6

我想合并它们以获得这样的结果:

 Pears Apples Oranges
1     1      3       4
2     2      2       6
3     3      1       6
4     1     Na       4
5     2     Na       6
6     3     Na       6

即,将它们按列名组合在一起,在第二帧缺少值的地方留下 Na/s,对于较大矩阵 a,较小矩阵 b 的一般情况

rbind 不起作用,merge 做了一些奇怪的事情。我追求什么?我也可以使用内存效率最高的东西,因为这最终会使用很多列名来完成很多次。

谢谢,

-N

编辑:当我最初问的时候,我可能应该提到这一点,但我实际上想达到上面的确切效果,但有一些非常重要的警告:

我正在使用矩阵

第一个矩阵将始终包含比第二个矩阵更多的列名

我可能想从包 bigmemory 创建一个 big.matrix。

【问题讨论】:

    标签: r matrix merge


    【解决方案1】:

    这是一种更通用的方法,如果您在 ab 中有多个需要添加的列:

    b.toAdd <- setdiff (names(a), names(b))
    if (length(b.toAdd))
      b[, b.toAdd] <- NA
    
    a.toAdd <- setdiff (names(b), names(a))
    if (length(a.toAdd))
      a[, a.toAdd] <- NA
    
    rbind(a, b)
    

    更新:

    刚刚注意到您关于需要内存效率的评论。 在这种情况下,您可能想要使用data.table,因为使用&lt;- 会创建不必要的副本。
    data.table istead 有一个:= 运算符,它的效率要高得多。

    library(data.table)
    a <- data.table(a)
    b <- data.table(b)
    
    
    if (length(b.toAdd <- setdiff (names(a), names(b))))
        b[, c(b.toAdd) := NA]
    
    if (length(a.toAdd <- setdiff (names(b), names(a))))
        a[, c(a.toAdd) := NA]
    
    rbind(a, b, use.names=TRUE)
    
    #    Pears Apples Oranges
    # 1:     1      3       4
    # 2:     2      2       6
    # 3:     3      1       6
    # 4:     1     NA       4
    # 5:     2     NA       6
    # 6:     3     NA       6
    

    在 SO 中搜索 [r] data.table benchmarks 以了解改进

    【讨论】:

    • 谢谢,但正如我编辑提到的,我使用的是矩阵,这对他们不起作用。我将 names() 更改为 colnames(),但在 b[, b.toAdd] 中出现错误
    • @N.McA。这个答案的第二部分应该仍然有效。 (即,使用a &lt;- data.table(matrix_a) 等...
    • 对,但我最终需要使用 bigmemory 来解决这个问题......或者 data.tables 是否允许我拥有文件支持的对象?
    • AFAIK,没有。但是,:= 背后的想法是不必为了添加一列而复制整个对象。因此,对内存的需求将减少,并且可能不需要昂贵的文件 I/O。最好的确定方法是进行实验。
    • 这种方法似乎也以某种方式将布尔值添加到我的数据中?我正在试验:P
    【解决方案2】:

    你可以使用:

    rbind(a, cbind(b, Apples=NA))
      Pears Apples Oranges
    1     1      3       4
    2     2      2       6
    3     3      1       6
    4     1     NA       4
    5     2     NA       6
    6     3     NA       6
    

    【讨论】:

      【解决方案3】:

      不太清楚你在追求什么,但你可以与添加的列合并(类似于 jmsinger 的回答):

      merge(a, cbind(b, Apples=NA), all=TRUE)
      ##   Pears Apples Oranges
      ## 1     1      3       4
      ## 2     1     NA       4
      ## 3     2      2       6
      ## 4     2     NA       6
      ## 5     3      1       6
      ## 6     3     NA       6
      

      【讨论】:

        猜你喜欢
        • 2017-04-22
        • 1970-01-01
        • 2014-06-08
        • 1970-01-01
        • 2021-11-01
        • 2017-10-31
        • 2021-11-29
        • 2013-02-23
        相关资源
        最近更新 更多