假设我有一个矩阵,

mat <- matrix((1:9)^2, 3, 3)

我可以像这样切片矩阵
> mat[2:3, 2]
[1] 25 36

如何将下标存储为变量? 也就是说,my_sub 应该是什么,使得
> mat[my_sub]
[1] 25 36
list 得到“无效的下标类型”错误。向量将失去多维性。似乎这样的基本操作没有适合这种用法的原始类型。

我知道我可以通过向量寻址访问矩阵,这意味着从 [2:3, 2] 转换为 c(5, 6) ,但该映射假定了解矩阵形状。如果我只是想要 [2:3, 2] 用于任何矩阵形状(假设它至少是那些尺寸)怎么办?

最佳答案

这里有一些替代方案。它们都可以推广到更高维的数组。

1) 矩阵下标 如果索引都是标量,除了可能是一个,如问题所示,那么:

mi <- cbind(2:3, 2)
mat[mi]

# test
identical(mat[mi],   mat[2:3, 2])
## [1] TRUE

在更高维度:
a <- array(1:24, 2:4)
mi <- cbind(2, 2:3, 3)
a[mi]

# test
identical(a[mi],   a[2, 2:3, 3])
## [1] TRUE

可以使用以下方法扩展它以消除标量限制:
L <- list(2:3, 2:3)
array(mat[as.matrix(do.call(expand.grid, L))], lengths(L))

然而,鉴于 (2) 也使用 do.call 但避免了对 expand.grid 的需要,它似乎不必要地复杂。

2) do.call 这种方法没有标量限制。 mata 来自上面:
L2 <- list(2:3, 1:2)
do.call("[", c(list(mat), L2))

# test
identical(do.call("[", c(list(mat), L2)),   mat[2:3, 1:2])
## [1] TRUE


L3 <- list(2, 2:3, 3:4)
do.call("[", c(list(a), L3))

# test
identical(do.call("[", c(list(a), L3)),   a[2, 2:3, 3:4])
## [1] TRUE

这可以通过定义来变得更漂亮:
`%[%` <- function(x, indexList) do.call("[", c(list(x), indexList))
mat %[% list(2:3, 1:2)
a %[% list(2, 2:3, 3:4)

关于r - 如何在R中将多维下标存储为变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46384600/

10-12 19:34