2011-11-02 76 views
6

有沒有人知道用整數/有效的方式來替換數組中的對角線元素,類似於對矩陣使用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循環(我的數組非常大,這個操作已經在循環內)。

非常感謝。

回答

6

試試這個:

with(expand.grid(a = 1:3, b = 1:3), replace(m, cbind(a, a, b), 5)) 

編輯:

要求當然整齊/有效,但是,這些都不是同樣的事情的問題。這裏的一個襯墊結構緊湊,無環路的,但如果你正在尋找的速度,我認爲你會發現,在這個問題的循環實際上是最快的所有的答案。

+0

+1非常好。它比我的功能代碼更快。 –

+0

不錯的工作,歡呼! – gjabel

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()的源代碼,以瞭解如何調整此代碼的順序。

+0

真棒,作品一種享受! – gjabel

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,但我沒有在這種情況下測試它。應該沒問題。

+0

它不創建DIMS> 2.對角矩陣它創建多個N×N的對角矩陣。 – papirrin