有没有人知道一种简洁/有效的方法来替换数组中的对角元素,类似于使用diag(x) <- value
作为矩阵?换句话说就是这样:
> m<-array(1:27,c(3,3,3))
> for(k in 1:3){
+ diag(m[,,k])<-5
+ }
> m
, , 1
[,1] [,2] [,3]
[1,] 5 4 7
[2,] 2 5 8
[3,] 3 6 5
, , 2
[,1] [,2] [,3]
[1,] 5 13 16
[2,] 11 5 17
[3,] 12 15 5
, , 3
[,1] [,2] [,3]
[1,] 5 22 25
[2,] 20 5 26
[3,] 21 24 5
但没有使用for循环(我的数组非常大,这种操作已经在循环中)。
非常感谢。
答案 0 :(得分:6)
试试这个:
with(expand.grid(a = 1:3, b = 1:3), replace(m, cbind(a, a, b), 5))
编辑:
这个问题要求整洁/高效,但当然,这些并不是一回事。这里的一个班轮是紧凑的,没有环路,但如果你正在寻找速度,我想你会发现问题中的循环实际上是所有答案中最快的。
答案 1 :(得分:5)
如果您的阵列中只有3个维,则可以使用以下功能。您可以根据此代码推广到更多维度,但我懒得为您做到这一点; - )
`arraydiag<-` <- function(x,value){
dims <- dim(x)
id <- seq_len(dims[1]) +
dims[2]*(seq_len(dims[2])-1)
id <- outer(id,(seq_len(dims[3])-1)*prod(dims[1:2]),`+`)
x[id] <- value
dim(x) <- dims
x
}
这就像:
m<-array(1:36,c(3,3,4))
arraydiag(m)<-NA
m
注意,与diag()函数相反,此函数不能处理非正方形的矩阵。您可以查看diag()的源代码,了解如何调整此代码的顺序。
答案 2 :(得分:3)
diagArr <-
function (dim)
{
n <- dim[2]
if(dim[1] != n) stop("expecting first two dimensions to be equal")
d <- seq(1, n*n, by=n+1)
as.vector(outer(d, seq(0, by=n*n, length=prod(dim[-1:-2])), "+"))
}
m[diagArr(dim(m))] <- 5
这是为了使其适用于高于3的尺寸,但在这种情况下我没有测试过它。应该没问题。