我想提取数组的反对角线
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:如何使用循环从数组中提取反对角线? (更好,更优雅的解决方案非常受欢迎)
答案 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
(假设m
在lapply
范围之外可用),因为我们也可以简单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