【问题标题】:How to aggregate matrices within a list based on vector of names?如何根据名称向量聚合列表中的矩阵?
【发布时间】:2016-01-20 08:20:52
【问题描述】:

我想根据存储在向量中的名称聚合(求和)列表中的矩阵。这里有一些示例数据:

lst <- list("111"=matrix(c(1, 0, 6, NA, 1, 0),
                              nrow = 1, byrow = T),
            "112"=matrix(c(6, 2, 2, 0, 3, NA),
                              nrow = 1, byrow = T),
            "113"=matrix(c(2, 3, 0, 0, 1, 1),
                         nrow = 1, byrow = T))
agg.nam <- c(111,113)

我的预期结果是:

> res
$
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    3    3    6    0    2    1

因此,将第一个和第三个矩阵相加(na.rm=TRUE)。

我首先尝试对 agg.nam 进行子集化:

lapply(lst, function(x) x[, which(names(x) %in% agg.nam)] )

但我在这一点上已经失败了,没有汇总。

【问题讨论】:

    标签: r list aggregate


    【解决方案1】:

    您可以使用以下方法将相关列表元素抓取到矩阵中:

    do.call(rbind, lst[as.character(agg.nam)])
    #      [,1] [,2] [,3] [,4] [,5] [,6]
    # [1,]    1    0    6   NA    1    0
    # [2,]    2    3    0    0    1    1
    

    然后所需的就是用na.rm=TRUE 调用colSums(感谢@docendodiscimus 指出这种简化):

    colSums(do.call(rbind, lst[as.character(agg.nam)]), na.rm=TRUE)
    # [1] 3 3 6 0 2 1
    

    如果矩阵有多行,上面的简化就不会真正起作用,下面会做得更好:

    # Grab relevant list elements
    mats <- lst[as.character(agg.nam)]
    
    # Replace any instance of NA with 0
    mats <- lapply(mats, function(x) {  x[is.na(x)] <- 0 ; x  })
    
    # Sum them up
    Reduce("+", mats)
    #      [,1] [,2] [,3] [,4] [,5] [,6]
    # [1,]    3    3    6    0    2    1
    

    【讨论】:

      【解决方案2】:

      1) abind 即使组成矩阵不是单行矩阵,这也有效。 abind 从子列表 L 中创建一个 3 维数组,然后使用 na.rm = TRUE 沿并行元素应用 sum

      library(abind)
      
      L <- lst[as.character(agg.nam)]
      apply(abind(L, along = 3), 1:2, sum, na.rm = TRUE)
      

      对于问题的输入数据,我们得到如下输出矩阵:

           [,1] [,2] [,3] [,4] [,5] [,6]
      [1,]    3    3    6    0    2    1
      

      2) 数组 这也有效,不使用任何包。除了使用arrayL 重塑为3d 数组外,它的工作原理相同。 L 来自上方。

      make3d <- function(List) array(unlist(List), c(dim(List[[1]]), length(List)))
      apply(make3d(L), 1:2, sum, na.rm = TRUE)
      

      3) mapply 使用mapply 这定义了一个并行求和,它删除了NA,然后使用Reduce 应用它。不使用任何包。 L 来自 (1)。

      psum <- function(x, y) array(mapply(sum, x, y, MoreArgs = list(na.rm = TRUE)), dim(x))
      Reduce(psum, L)
      

      3a) (3) 的变体是:

      sumNA <- function(...) sum(..., na.rm = TRUE)
      array(do.call(mapply, c(sumNA, L)), dim(L[[1]]))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-28
        • 1970-01-01
        • 2021-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-01
        • 1970-01-01
        相关资源
        最近更新 更多