如果我有一个名词的二维阵列可以通过一米切片 * 名词的矩阵这样的
a <- array(1:27,c(3,3,3))
b <- matrix(rep(1:3,3),3)
# This will return the index a[1,1,1] a[2,2,2] and a[3,3,3]
a[b]
# Output
[1] 1 14 27
是否有任何“有效且简单”的方法来做一个类似的切片,但保持一些尺寸免费? 这是一个带有 m * (n-i)维数组的n维数组和 得到 i + 1 维数组作为结果。
a <- array(1:27,c(3,3,3))
b <- matrix(rep(1:2,2),2)
# This will return a vector of the index a[1] a[2] a[1] and a[2]
a[b]
# Output
[1] 1 2 1 2
# This will return the indexes of the cartesian product between the vectors,
# that is a array consisting of a[1,,1] a[1,,2] a[2,,1] and a[2,,2]
a[c(1,2),,c(1,2)]
# Output
, , 1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
, , 2
[,1] [,2] [,3]
[1,] 10 13 16
[2,] 11 14 17
如果最后一个命令返回一个数组,则应该是所需的结果 用[1,,1]和[2,,2]。 现在我用for循环和abind解决了这个问题,但我确信必须有更好的方法。
# Desired functionality
a <- array(1:27,c(3,3,3))
b <- array(c(c(1,2),c(1,2)),c(2,2))
sliceem(a,b,freeDimension=2)
# Desired output (In this case rbind(a[1,,1],a[2,,2]) )
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 11 14 17
答案 0 :(得分:3)
我认为这是最干净的方法 - 制作一个单独的功能:
slicem <- function(a,idx,drop=FALSE) do.call(`[`,c(list(a),idx,list(drop=drop)))
# usage for OP's example
a <- array(1:27, c(3,3,3))
idx <- list(1:2, TRUE, 1:2)
slicem(a,idx)
给出了
, , 1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
, , 2
[,1] [,2] [,3]
[1,] 10 13 16
[2,] 11 14 17
您必须为未选择的每个维度编写TRUE
。
遵循OP的新期望......
library(abind)
nistfun <- function(a,list_o_idx,drop=FALSE){
lens <- lengths(list_o_idx)
do.call(abind, lapply(seq.int(max(lens)), function(i)
slicem(a, mapply(`[`, list_o_idx, pmin(lens,i), SIMPLIFY=FALSE), drop=drop)
))
}
# usage for OP's new example
nistfun(a, idx)
# , , 1
#
# [,1] [,2] [,3]
# [1,] 1 4 7
#
# , , 2
#
# [,1] [,2] [,3]
# [1,] 11 14 17
现在,任何非TRUE
索引必须具有相同的长度,因为它们将匹配。
abind
而不是rbind
(请参阅此答案的早期编辑),因为这是考虑切片数组的唯一明智的一般方法。如果你真的想要删除维度,那么它应该被删除以及如何删除它是非常模糊的,所以单独返回向量:
nistfun(a, idx, drop=TRUE)
# [1] 1 4 7 11 14 17
如果你想把它扔回某种数组中,你可以在事后:
matrix( nistfun(a, idx), max(lengths(idx)), dim(a)[sapply(idx,isTRUE)]), byrow=TRUE)
# [,1] [,2] [,3]
# [1,] 1 4 7
# [2,] 11 14 17