从阵列中提取反对角线

时间:2013-08-21 08:43:34

标签: arrays r loops

我想提取数组的反对角线

m=array(1:18,c(3,3,2))

我最好的镜头

k=dim(m)[3]

mn=matrix(nrow = k, ncol = 3)

for (i in 1:k){
  mn=diag(m[,,i][3:1,1:3])
  }

这将返回12 14 16,即阵列中第二个矩阵的反对角线。我想实现这个

[1] 3  5  7
[2] 12 14 16

我希望“anti-diags”作为数组

手动diag(m[,,1][3:1,1:3])diag(m[,,2][3:1,1:3])工作正常,但我正在使用的数组是dim(c(3,3,22)),所以我想“循环!”

MQ:如何使用循环从数组中提取反对角线? (更好,更优雅的解决方案非常受欢迎)

2 个答案:

答案 0 :(得分:2)

这应该有效:

mn <- array(NA, dim=dim(m))
for (i in 1:dim(m)[3]){
   mn[,,i]=diag(m[,,i][cbind(3:1,1:3)])
              }

目前还不清楚你是否希望“反诊断”成为新的诊断,但这就是你的代码所暗示的意图。形式matrix[cbind(vec1,vec2)]从矩阵中提取(R,C)引用的元素。

如果您不希望它们作为数组,那么这是另一个结果:

 mn <- array(NA, dim=c(2,3))
     for (i in 1:dim(m)[3]){
        mn[i,]=m[,,i][cbind(3:1,1:3)]
                            }
 mn
     [,1] [,2] [,3]
[1,]    3    5    7
[2,]   12   14   16

这是获得相同值的无循环方式:

 m[cbind( rep(3:1,2), rep(1:3,2), rep(1:2,each=3)) ]
[1]  3  5  7 12 14 16

答案 1 :(得分:1)

您可以在第三维度上使用lapply并通过首先旋转矩阵(see this great answer)来提取反对角线,方法是反转列顺序并采用对角线。基本上就是这样......

out <- lapply( 1:dim(m)[3] , function(x) diag( t( apply( m[,,x] , 2 , rev ) ) ) )
[[1]]
[1] 3 5 7

[[2]]
[1] 12 14 16

如果您需要将它们粘在一起作为数组,请使用do.call ...

do.call( rbind , out )
     [,1] [,2] [,3]
[1,]    3    5    7
[2,]   12   14   16

在这种特殊情况下,for循环很多更快(基准测试),您应该使用@DWin的答案。

我觉得我们可以简单一点,避免使用列表和错误使用lapply(假设mlapply范围之外可用),因为我们也可以简单apply跨越矩阵的第三维。所以我们可以apply一次旋转矩阵,然后像每个旋转矩阵一样diag ...

rotM <- apply( m , 2:3 , rev )    
out <- t( apply( rotM , 3 , diag ) )
     [,1] [,2] [,3]
[1,]    3    5    7
[2,]   12   14   16