沿数组第三维的子集应用sum

时间:2018-01-19 19:14:02

标签: arrays r apply seq

我有以下对象:

A :1个数组,包含x,y,z,尺寸 - >包含变量(温度)

B & C :具有x,y维度的2个数组 - >包含沿A< s 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)

如果有人知道如何通过应用或其他清洁解决方案使这个功能可行,那就太棒了。

非常感谢!

1 个答案:

答案 0 :(得分:1)

这对基础R来说不是一个非常好的任务,我宁愿在缺少已经这样做的包(C)的情况下用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)