This question already has an answer here:
-
How to replace non-diagonal elements in a matrix?
6 answers
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!
In R, the diag
method has two functions.
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
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
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…
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