R中的不规则数组子集

时间:2013-07-17 17:48:19

标签: arrays r subset

假设我有阵列

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)),]

这适用于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)),]以便按预期工作吗?也许我只是缺少一些语法糖......

2 个答案:

答案 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))会被回收。