沿数组第 3 维的子集应用总和

apply sum along subsets of array 3rd dimension

我有以下对象:

A:1 个具有 x、y、z 维度的数组 -> 包含一个变量(温度)

B & C:2 个 x、y 维度的数组 -> 包含沿 A 的 z 维度的向量索引

A <- array(rnorm(n = 12*4*3*5), dim = c(4,3,5))
dimnames(A) <- list("x" = c(1:4), "y" = c(1:3), "z" = c(1:5))

B <- matrix(rep(c(2:1), 6), nrow = 4)
dimnames(B) <- list("x" = c(1:4), "y" = c(1:3))
C <- matrix(rep(c(4:5), 6), nrow = 4)
dimnames(C) <- list("x" = c(1:4), "y" = c(1:3))

我正在寻找一种方法,仅在 B 和 C 指示的索引之间应用跨 z 维度的 A 之和。

如果我有一个向量而不是 3D 数组,我会这样解决它:

> A <- round(c(rnorm(5)), 1)
> B <- 2 #index of first value to sum
> C <- 4 #index of last value to sum
> vindex <- seq(B,C,1)
> A
[1]  0.0 -0.9 -1.1 -1.7 -0.4
> vindex
[1] 2 3 4
> sum(A[vindex])
[1] -3.7
>

# or better with a function

> foo <- function(x, start_idx, end_idx) {
+   vidx <- seq(start_idx, end_idx, 1)
+   return(sum(x[vidx]))
+ }
> 
> foo(A,B,C)
[1] -3.7

不幸的是,seq() 不接受向量作为参数,因此使用 apply 函数并不简单。如果又是 A[x,y,z] 和 B 和 C[x,y]:

> apply(A,c(1,2),foo,B,C)
Error in seq.default(start_idx, end_idx, 1) : 'from' must be of length 1
Called from: seq.default(start_idx, end_idx, 1)

如果有人知道如何使用 apply 或其他干净的解决方案使此功能可用,那就太好了。

非常感谢!

这对于基础 R 来说不是一个很好的任务,在没有已经这样做的包的情况下,我更愿意在 C++ 中实现它 (?)。

从逻辑上讲,针对您的问题的简单但矢量化的解决方案可以构造为:

# initialize index array
D <- array(
  1, 
  dim = c(4,3,5), 
  dimnames = list(x = letters[1:4], y = letters[1:3], z = letters[1:5])
)

# set indices out of bounds to zero
E <- rep(1:5, each = 4*3)
BB <- rep(B, times = 5)
D[E < BB] <- 0
CC <- rep(C, times = 5)
D[E > CC] <- 0

# multiply with index array and sum
apply(A * D, c(1,2), sum)