【问题标题】:Cumulative multidimensional array sum in RR中的累积多维数组和
【发布时间】:2019-09-20 00:08:25
【问题描述】:

在R中,如何将矩阵不同边距上累积和的计算推广到多维数组?

例如,给定矩阵

a2 <- array(1:6, dim = c(2,3))
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

可以使用apply计算不同边距上的累积和:

apply(a2, 2, cumsum)
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    3    7   11
t(apply(a2, 1, cumsum))
     [,1] [,2] [,3]
[1,]    1    4    9
[2,]    2    6   12

请注意,在后一种情况下需要进行一些重塑。现在的问题是:

如何计算多维数组的累积和?

例如,对于像这样的三维数组:

a3 <- array(1:24, dim = c(2,3,4))

我对行、列和第三维的累积和感兴趣,保留原始数组的结构。具体来说,行累计和应该是:

, , 1

     [,1] [,2] [,3]
[1,]    1    4    9
[2,]    2    6   12

, , 2

     [,1] [,2] [,3]
[1,]    7   16   27
[2,]    8   18   30

, , 3

     [,1] [,2] [,3]
[1,]   13   28   45
[2,]   14   30   48

, , 4

     [,1] [,2] [,3]
[1,]   19   40   63
[2,]   20   42   66

n 维数组的答案是什么?

【问题讨论】:

    标签: arrays r apply


    【解决方案1】:

    一种方法是使用旧的 for 循环

    res <- a3
    for (k in 1:dim(a3)[3]) res[, , k] <- t(apply(a3[, , k], 1, cumsum))
    res
    #, , 1
    #
    #     [,1] [,2] [,3]
    #[1,]    1    4    9
    #[2,]    2    6   12
    #
    #, , 2
    #
    #     [,1] [,2] [,3]
    #[1,]    7   16   27
    #[2,]    8   18   30
    #
    #, , 3
    #
    #     [,1] [,2] [,3]
    #[1,]   13   28   45
    #[2,]   14   30   48
    #
    #, , 4
    #
    #     [,1] [,2] [,3]
    #[1,]   19   40   63
    #[2,]   20   42   66
    

    【讨论】:

    • 对于 n 个维度,您需要 n-2 个嵌套 for 循环,对吧?
    • @dzeltzer 如果您总是想从前两个维度计算二维矩阵的行-cumsum,那么可以。
    【解决方案2】:

    这几乎给出了你想要的,但结果被转置了

    apply(a3, c(1, 3), cumsum)
    
    #, , 1
    
    #     [,1] [,2]
    #[1,]    1    2
    #[2,]    4    6
    #[3,]    9   12
    
    #, , 2
    
    #     [,1] [,2]
    #[1,]    7    8
    #[2,]   16   18
    #[3,]   27   30
    
    #, , 3
    
    #     [,1] [,2]
    #[1,]   13   14
    #[2,]   28   30
    #[3,]   45   48
    
    #, , 4
    
    #     [,1] [,2]
    #[1,]   19   20
    #[2,]   40   42
    #[3,]   63   66
    

    我不知道我们如何在同一个apply 调用中转置结果(应该有办法)。我试过了

    t(apply(a3, c(1, 3), cumsum))
    apply(a3, c(1, 3), function(x) t(cumsum(x)))
    

    但这不起作用。但是,现在如果我们再次使用apply 并转置,我们可以恢复原始结构。

    apply(apply(a3, c(1, 3), cumsum), c(1, 3), t)
    

    【讨论】:

      【解决方案3】:

      使用apply,后跟aperm。唯一棘手的部分是正确设置边距:

      aperm(apply(a3, -2, cumsum), c(2, 1, 3))
      

      这些也都有效:

      aperm(apply(a3, c(1, 3), cumsum), c(2, 1, 3))
      
      aperm(apply(a3, c(3, 1), cumsum), c(3, 1, 2))
      
      apply(apply(a3, -2, cumsum), -2, c)
      
      apply(apply(a3, c(1, 3), cumsum), c(1, 3), c)
      
      library(plyr)
      aa <- aperm(aaply(a3, c(1, 3), cumsum), c(1, 3, 2))
      dimnames(aa) <- NULL
      

      【讨论】:

      • aperm 是我一直在寻找的t 的泛化!
      【解决方案4】:

      从@G 推断。格洛腾迪克的回答,这个函数使用aperm 来计算 n 维数组任意边距上的累积和:

      array_cumsum <- function(a, margin) {
        n <- length(dim(a))
        permorder <- append(x = 2:n, 1, margin - 1)
        aperm(apply(a, -margin, cumsum), permorder)
      }
      

      例如,为了便于观察累积和,使用一个简单的数组,该函数可用于计算第二维的边距:

      a <- array(1, dim = c(2,3,4))
      array_cumsum(a3, 2)
      # , , 1
      # 
      # [,1] [,2] [,3]
      # [1,]    1    2    3
      # [2,]    1    2    3
      # 
      # , , 2
      # 
      # [,1] [,2] [,3]
      # [1,]    1    2    3
      # [2,]    1    2    3
      # 
      # , , 3
      # 
      # [,1] [,2] [,3]
      # [1,]    1    2    3
      # [2,]    1    2    3
      # 
      # , , 4
      # 
      # [,1] [,2] [,3]
      # [1,]    1    2    3
      # [2,]    1    2    3
      

      以及第三维:

      array_cumsum(a3, 3)
      # , , 1
      # 
      # [,1] [,2] [,3]
      # [1,]    1    1    1
      # [2,]    1    1    1
      # 
      # , , 2
      # 
      # [,1] [,2] [,3]
      # [1,]    2    2    2
      # [2,]    2    2    2
      # 
      # , , 3
      # 
      # [,1] [,2] [,3]
      # [1,]    3    3    3
      # [2,]    3    3    3
      # 
      # , , 4
      # 
      # [,1] [,2] [,3]
      # [1,]    4    4    4
      # [2,]    4    4    4
      

      【讨论】:

        猜你喜欢
        • 2016-07-11
        • 1970-01-01
        • 1970-01-01
        • 2015-11-20
        • 2021-08-19
        • 1970-01-01
        • 1970-01-01
        • 2018-08-17
        • 1970-01-01
        相关资源
        最近更新 更多