2

假设我有数组

TestArray=array(1:(3*3*4),c(3,3,4))

在下文中,我将分别将TestArray[i,,]TestArray[,j,]TestArray[,,k] 称为x=iy=jz=k子集。在此特定示例中,索引ij可以从 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)),]

这适用于二维

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)),]以使其按需要工作吗?也许我只是缺少一些语法糖...

4

2 回答 2

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)
于 2013-07-17T18:13:12.250 回答
1

除了 Ben 的回答之外,这里对我的原始代码行进行了令人惊讶的简单修改,即可完成这项工作。

matrix(TestArray[as.matrix(Diagonal(3,TRUE))],ncol=3,nrow=4,byrow=TRUE)

这是有效的,因为as.matrix(Diagonal(3,TRUE))被回收了。

于 2013-07-17T20:15:47.887 回答