【问题标题】:how to merge matrices in R with different number of rows如何在R中合并具有不同行数的矩阵
【发布时间】:2016-11-01 00:11:17
【问题描述】:

我想使用它们的行名合并几个矩阵。 这些矩阵的行数和列数不同。 例如:

m1 <- matrix(c(1, 2, 3, 4, 5, 6), 3, 2)
rownames(m1) <- c("a","b","c")
m2 <- matrix(c(1, 2, 3, 5, 4, 5, 6, 2), 4, 2)
rownames(m2) <- c("a", "b", "c", "d")
m3 <- matrix(c(1, 2, 3, 4), 2,2)
rownames(m3) <- c("d", "e")

mlist <- list(m1, m2, m3)

对于他们,我想得到:

Row.names    V1.x    V2.x    V1.y    V2.y   V1.z    V2.z
        a     1       4       1       4      NA      NA
        b     2       5       2       5      NA      NA
        c     3       6       3       6      NA      NA
        d    NA      NA       5       2       1       3
        e    NA      NA      NA      NA       2       4

我已尝试将 lapply 与函数合并一起使用:

M <- lapply(mlist, merge, mlist, by = "row.names", all = TRUE)

但是,它不起作用:

data.frame(c(1, 2, 3, 4, 5, 6), c(1, 2, 3, 5, 4, 5, 6, 2), c(1, :
参数意味着不同的行数:3、4、2

有没有一种优雅的方式来合并这些矩阵?

【问题讨论】:

    标签: r matrix merge


    【解决方案1】:

    您正在尝试对矩阵列表应用缩减 (?Reduce),其中缩减基本上是 merge。问题是merge(m1, m2, by = "row.names", all = T) 不会为您提供一个带有行名的新合并矩阵,而是返回第一列中的行名。这就是为什么我们需要在归约函数中添加额外的逻辑。

    Reduce(function(a,b) {
             res <- merge(a,b,by = "row.names", all = T); 
             rn <- res[,1]; # Row.names column of merge
             res <- res[,-1]; # Actual data
             row.names(res) <- rn; # Assign row.names
             return(res) # Return the merged data with proper row.names
           }, 
           mlist[-1], # Reduce (left-to-right) by applying function(a,b) repeatedly
           init = mlist[[1]] # Start with the first matrix
    )
    

    【讨论】:

      【解决方案2】:

      或者:

      df <- mlist[[1]]
      for (i in 2:length(mlist)) {
          df <- merge(df, mlist[[i]], by = "row.names", all=T)
          rownames(df) <- df$Row.names
          df <- df[ , !(names(df) %in% "Row.names")]  
      }
      
        # V1.x V2.x V1.y V2.y V1 V2
      # a    1    4    1    4 NA NA
      # b    2    5    2    5 NA NA
      # c    3    6    3    6 NA NA
      # d   NA   NA    5    2  1  3
      # e   NA   NA   NA   NA  2  4
      

      【讨论】:

        【解决方案3】:

        如果将正确的长格式 data.frame 传递给函数,这也可以概念化为 reshape 操作:

        tmp <- do.call(rbind, mlist)
        tmp <- data.frame(tmp, id=rownames(tmp),
                          time=rep(seq_along(mlist),sapply(mlist,nrow)) )
        reshape(tmp, direction="wide")
        
        #  id X1.1 X2.1 X1.2 X2.2 X1.3 X2.3
        #a  a    1    4    1    4   NA   NA
        #b  b    2    5    2    5   NA   NA
        #c  c    3    6    3    6   NA   NA
        #d  d   NA   NA    5    2    1    3
        #e  e   NA   NA   NA   NA    2    4
        

        【讨论】:

          猜你喜欢
          • 2022-11-24
          • 1970-01-01
          • 1970-01-01
          • 2014-04-22
          • 1970-01-01
          • 2014-05-04
          • 1970-01-01
          • 2014-09-09
          • 2016-05-27
          相关资源
          最近更新 更多