Home > Software design >  Replacing upper triangular matrix elements in row order
Replacing upper triangular matrix elements in row order

Time:02-01

I have a square matrix as follows.

> ex_mat
          [,1]      [,2]      [,3]      [,4]
[1,] 0.4270634 2.1920890 0.5647472 1.7149861
[2,] 2.0556220 1.1157322 2.6723637 0.3155507
[3,] 1.2252602 0.1063053 0.6396099 0.7903348
[4,] 0.3614062 1.1118661 0.5000143 0.2491543

I've ranked the upper off-diagonal part of the matrix in row order (from largest to smallest) with this.

> rank(-(t(ex_mat)[lower.tri(ex_mat)]))
[1] 2 5 3 1 6 4

I want to replace the upper off-diagonal elements of "ex_mat" with the ranks obtained above. I'm using https://statisticsglobe.com/modify-diagonal-lower-upper-triangular-part-matrix-r as example code. While my ranks are correct, the code seems to be inserting the ranks in column order.

> ex_mat_new <- ex_mat
> ex_mat_new[upper.tri(ex_mat_new)] <- rank(-(t(ex_mat)[lower.tri(ex_mat)]))
> ex_mat_new
          [,1]      [,2]      [,3]      [,4]
[1,] 0.4270634 2.0000000 5.0000000 1.0000000
[2,] 2.0556220 1.1157322 3.0000000 6.0000000
[3,] 1.2252602 0.1063053 0.6396099 4.0000000
[4,] 0.3614062 1.1118661 0.5000143 0.2491543

How can I fix this? [1,4] and [2,3] are off. Thank you.

CodePudding user response:

The value insertions are in column order (in matrix, data.frame). We may assign on the lower.tri and then get the transpose

ex_mat_new[lower.tri(ex_mat_new)] <- rank(-(t(ex_mat)[lower.tri(ex_mat)]))
ex_mat_new <- t(ex_mat_new)
ex_mat_new[lower.tri(ex_mat_new)] <- ex_mat[lower.tri(ex_mat)]

-output

> ex_mat_new
          [,1]      [,2]      [,3]      [,4]
[1,] 0.4270634 2.0000000 5.0000000 3.0000000
[2,] 2.0556220 1.1157322 1.0000000 6.0000000
[3,] 1.2252602 0.1063053 0.6396099 4.0000000
[4,] 0.3614062 1.1118661 0.5000143 0.2491543

or this can be done in a single line with replace

t(replace(t(ex_mat), lower.tri(ex_mat), rank(-(t(ex_mat)[lower.tri(ex_mat)]))))

-output

       [,1]      [,2]      [,3]      [,4]
[1,] 0.4270634 2.0000000 5.0000000 3.0000000
[2,] 2.0556220 1.1157322 1.0000000 6.0000000
[3,] 1.2252602 0.1063053 0.6396099 4.0000000
[4,] 0.3614062 1.1118661 0.5000143 0.2491543

data

ex_mat <- structure(c(0.4270634, 2.055622, 1.2252602, 0.3614062, 2.192089, 
1.1157322, 0.1063053, 1.1118661, 0.5647472, 2.6723637, 0.6396099, 
0.5000143, 1.7149861, 0.3155507, 0.7903348, 0.2491543), .Dim = c(4L, 
4L), .Dimnames = list(NULL, NULL))
  •  Tags:  
  • Related