假设我有阵列
TestArray=array(1:(3*3*4),c(3,3,4))
在下文中,我将分别将TestArray[i,,]
,TestArray[,j,]
和TestArray[,,k]
称为x=i
,y=j
和z=k
子集。在此特定示例中,索引i
和j
可以从1到3,k
从1到4。
现在,我想将这个3维数组子集化,以便得到x=y
子集。输出应为
do.call("cbind",
list(TestArray[1,1,,drop=FALSE],
TestArray[2,2,,drop=FALSE],
TestArray[3,3,,drop=FALSE]
)
)
我(天真地)认为应该可以通过
进行这样的操作library(Matrix)
TestArray[as.array(Diagonal(3,TRUE)),]
这适用于2维
matrix(1:9,3,3)[as.matrix(Diagonal(3,TRUE))]
但是,在3个维度中,它会出错。
我知道我可以生成一个索引数组
IndexArray=outer(diag(1,3,3),c(1,1,1,1),"*")
mode(IndexArray)="logical"
并通过
访问元素matrix(TestArray[IndexArray],nrow=4,ncol=3,byrow=TRUE)
但是第一种方法会更好,并且需要更少的内存。你知道我如何修复TestArray[as.array(Diagonal(3,TRUE)),]
以便按预期工作吗?也许我只是缺少一些语法糖......
答案 0 :(得分:1)
我不知道abind::asub
是否会做我想要的事情。这使用了比你上面更有效的矩阵索引形式,但我还是要把结果强制成正确的形状......
indmat <- cbind(1:3,as.matrix(expand.grid(1:3,1:4)))
matrix(TestArray[indmat],nrow=4,ncol=3,byrow=TRUE)
略微更普遍:
d <- dim(TestArray)[1]
d2 <- dim(TestArray)[3]
indmat <- cbind(1:d,as.matrix(expand.grid(1:d,1:d2))
matrix(TestArray[indmat],nrow=d2,ncol=d,byrow=TRUE)
答案 1 :(得分:1)
除了Ben的答案之外,这里还有一个令人惊讶的简单修改我原来的代码行。
matrix(TestArray[as.matrix(Diagonal(3,TRUE))],ncol=3,nrow=4,byrow=TRUE)
这可行,因为as.matrix(Diagonal(3,TRUE))
会被回收。