Replacing non-diagonal elements in a matrix in R (hopefully a better asked this time) [duplicate]

时光总嘲笑我的痴心妄想 提交于 2020-01-05 10:37:08

问题


Okay, I asked this question earlier but I got bashed (deservedly) for not specifying anything and showing no sign of previous attempt. So let me try again..

I'm using R, and I have a 463✕463 matrix. What I would like to do is to replace all elements other than the diagonal ones (X11, X22, X33,...,Xjj) with zero.

E.g. I want:

[1 4 5
 2 3 5
 3 9 8]

to be:

[1 0 0
 0 3 0
 0 0 8]

When I use the diag() function, it simply gives me a column vector of the diagonal values. I imagine I can use the replace() function somehow combined with a "if not diagonal" logic...but I am lost.

And yes, as some here have guessed, I am probably much younger than many people here and am completely new at this...so please put me in the right direction. Really appreciate all your help!


回答1:


In R, the diag method has two functions.

  1. It returns the diagonal of a matrix. I.e.

    m <- matrix(1:9, ncol=3)
    m
    #      [,1] [,2] [,3]
    # [1,]    1    4    7
    # [2,]    2    5    8
    # [3,]    3    6    9
    diag(m)
    # [1] 1 5 9
    
  2. It can construct a diagonal matrix.

    diag(1:3)
    #      [,1] [,2] [,3]
    # [1,]    1    0    0
    # [2,]    0    2    0
    # [3,]    0    0    3
    

So in your case, extract the diagonal from your existing matrix and supply it to diag:

diag(diag(m))
#      [,1] [,2] [,3]
# [1,]    1    0    0
# [2,]    0    5    0
# [3,]    0    0    9



回答2:


using outer

You can use the following to compute a logical matrix which describes the non-diagonal entries of a n×n matrix:

outer(1:n, 1:n, function(i,j) i!=j)

Applied to your example:

> m <- matrix(c(1,2,3,4,3,9,5,5,8),ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    4    5
[2,]    2    3    5
[3,]    3    9    8
> m[outer(1:3, 1:3, function(i,j) i!=j)] <- 0
> m
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    3    0
[3,]    0    0    8

using triangles

A possible alternative would be combining the two triangles on either side of the diagonal. In this case, you use the matrix m itself as input to determine the size.

upper.tri(m) | lower.tri(m)

Applied to your use case:

> m[upper.tri(m) | lower.tri(m)] <- 0

It seems you already got this answer in response to your original post…




回答3:


m[ col(m)==row(m) ] <- 0

> m <- matrix(1:9, 3)
> m[ col(m)==row(m) ]
[1] 1 5 9
> m[ col(m)!=row(m) ] <- 0
> m
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    5    0
[3,]    0    0    9


来源:https://stackoverflow.com/questions/16706578/replacing-non-diagonal-elements-in-a-matrix-in-r-hopefully-a-better-asked-this

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!