R 索引数组。如何通过使用第 3 维矩阵来索引 3 维数组

R indexing arrays. How to index 3 dimensional array by using a matrix for the 3rd dimension

我有一个关于索引 3 个暗淡数组的问题。

假设我有一个 3 维数组

x<- c(1:36)
dim(x) <- c(3,4,3) 

现在我想根据包含所有 [i,j] 个位置的第 3 维索引的矩阵从该数组中提取值。

y <- c(rep(1,4),rep(2,4),rep(3,4))
dim(y) <- c(3,4)

y
      [,1] [,2] [,3] [,4]
[1,]    1    1    2    3
[2,]    1    2    2    3
[3,]    1    2    3    3

所以结果应该是这样的:

     [,1] [,2] [,3] [,4]
[1,]    1    4   19   34
[2,]    2   17   20   35
[3,]    3   18   33   36

有什么优雅的方法可以做到这一点吗?我知道如何使用两个 for 循环遍历数组,但这对我的数据来说太慢了。

help("[") 告诉我们:

Matrices and arrays

[...]

A third form of indexing is via a numeric matrix with the one column for each dimension: each row of the index matrix then selects a single element of the array, and the result is a vector.

因此,我们将您的 y 矩阵转换为符合此的形状。

library(reshape2)
z <- x[as.matrix(melt(y))]
dim(z) <- dim(y)
#     [,1] [,2] [,3] [,4]
#[1,]    1    4   19   34
#[2,]    2   17   20   35
#[3,]    3   18   33   36

我将此视为一些代码高尔夫的机会。绝对可以单行执行此操作:

> `dim<-`(x[cbind(c(row(y)), c(col(y)), c(y))], dim(y))
     [,1] [,2] [,3] [,4]
[1,]    1    4   19   34
[2,]    2   17   20   35
[3,]    3   18   33   36

如@Roland 的回答所示,matrix/array 索引涉及创建一个 n 列矩阵并将列设置为等于每个维度的行、列等位置n维数组。我们可以使用row()col()函数来提取y中每个元素的行列位置:

> row(y)
     [,1] [,2] [,3] [,4]
[1,]    1    1    1    1
[2,]    2    2    2    2
[3,]    3    3    3    3
> col(y)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    1    2    3    4
[3,]    1    2    3    4

y本身给出了三维位置。将每个包装在 c() 中将它们变成一个向量,这样它们就可以 cbind-ed 在一起创建一个提取矩阵。

然后,dim<-() 的一些有趣用法可以将所有内容放在一行中。