Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a matrix symmetric

Tags:

r

matrix

I have a matrix that should be symmetric according to theory, but might not be observed as symmetric in my data. I would like to force this to be symmetric by using the maximum of the two compared cells.

test_matrix <- matrix(c(0,1,2,1,0,1,1.5,1,0), nrow = 3)
test_matrix
#>     [,1] [,2] [,3]
#>[1,]    0    1  1.5
#>[2,]    1    0  1.0
#>[3,]    2    1  0.0

It's easy enough to do this with a double loop.

for(i in 1:3){
  for(j in 1:3){
    test_matrix[i, j] <- max(test_matrix[i, j], test_matrix[j, i]) 
   }
}
test_matrix
#>      [,1] [,2] [,3]
#> [1,]    0    1    2
#> [2,]    1    0    1
#> [3,]    2    1    0

But my matrix is larger than $3x3$, and R's problems with loops are well-documented. I'm also interested in making my code as clean as possible. In fact, I considered putting this on code golf, but this is a real problem that I think others might be interested in.

I've seen this one as well as this one, but mine is different in that those op's seemed to actually have a symmetric matrix that just needed reordering, and I have a matrix that I need to change to be symmetric.

like image 720
gregmacfarlane Avatar asked Jan 08 '23 12:01

gregmacfarlane


1 Answers

You could use pmax(), which returns the element-wise maxima of a pair of vectors.

pmax(test_matrix, t(test_matrix))
#      [,1] [,2] [,3]
# [1,]    0    1    2
# [2,]    1    0    1
# [3,]    2    1    0

It'll work with a pair of matrices, as here, because: (1) in R, matrices are 'just' vectors with attached (dimension) attributes; and (2) the code used to implement pmax() is nice enough to reattach the attributes of it's first argument to the value that it returns.

like image 56
Josh O'Brien Avatar answered Jan 18 '23 19:01

Josh O'Brien