1

I have a matrix with the lower triangle filled and want to fill the upper triangle of the matrix with the lower triangle's matching values.

The code I have been trying is :

    r <-  read.table("rcorrected.csv", header = TRUE, sep = ",", check.names = FALSE)
    m <- as.matrix(r)


m[upper.tri(m, diag = FALSE)] <- m[lower.tri(m, diag= FALSE)]

Output:

Warning message:
In m[upper.tri(m, diag = FALSE)] <- m[lower.tri(m, diag = FALSE)] :
  number of items to replace is not a multiple of replacement length


    structure(m)
            1    2    3    4    5    6    7    8    9   10   11   12
 [1,]  1 1.00   NA   NA   NA   NA   NA   NA   NA   NA   NA   NA   NA
 [2,]  2 0.50 1.00   NA   NA   NA   NA   NA   NA   NA   NA   NA   NA
 [3,]  3 0.57 0.50 1.00   NA   NA   NA   NA   NA   NA   NA   NA   NA
 [4,]  4 0.00 0.04 0.16 1.00   NA   NA   NA   NA   NA   NA   NA   NA

dput(head(m[, c(2,1)]))
    structure(c(1, 0.5, 0.57, 0, 0, 0.23, 1, 2, 3, 4, 5, 6), .Dim = c(6L, 
    2L), .Dimnames = list(NULL, c("1", "")))

Is the matrix m, being read as a list?

twhitney
  • 25
  • 5
  • 1
    A [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) would be helpful. Right now, we have no data to run your code on, can't see the data you're working with, and can't see either the output you have or the output you want. Searching SO is showing me a lot of related posts already up, but it's unclear what exactly you want – camille Jan 09 '20 at 19:22

2 Answers2

2

Here, we are assigning with unequal number of observations with diag = TRUE on the rhs of assignment and also the diag = TRUE should be inside the lower.tri and not outside the function

m[upper.tri(m, diag = FALSE)] <- m[lower.tri(m, diag= FALSE)]
akrun
  • 874,273
  • 37
  • 540
  • 662
  • I have added dput, and with the code: m[upper.tri(m, diag = TRUE)] <- m[lower.tri(m, diag= TRUE)], I get an error stating Warning message: In m[upper.tri(m, diag = TRUE)] <- m[lower.tri(m, diag = TRUE)] : number of items to replace is not a multiple of replacement length, and I double checked and my column and rows are the same length – twhitney Jan 09 '20 at 19:42
  • @twhitney Your `dput` shows as a `list` and not a `matrix`. Can you please check it – akrun Jan 09 '20 at 19:43
  • as.matrix(m) is saying TRUE and when I check my dput(r) and dput(m) it says list but the CSV is a matrix and I added the structure of m – twhitney Jan 09 '20 at 21:12
  • 1
    @twhitney ; you are running in to difficulties because of the line `m <- matrix(r)`. This should be `m <- as.matrix(r)` – user20650 Jan 09 '20 at 22:22
  • @akrun, thanks for all the help I updated with my current script and error that is still coming back – twhitney Jan 10 '20 at 20:14
  • @twhitney If i check your new dput, it is not a symmetric matrix i.e. `upper.tri(m, diag = FALSE)` TRUEs not equal to `lower.tri(m, diag= FALSE)` – akrun Jan 10 '20 at 20:16
1

If m is a matrix such as that shown in the Note at the end with the lower triangle filled then this fills the upper triangular part too.

m2 <- m + t(m)
m2
##      [,1] [,2] [,3] [,4]
## [1,]    0    5    9   13
## [2,]    5    0   10   14
## [3,]    9   10    0   15
## [4,]   13   14   15    0

If the diagonal of m is not 0 then do it this way:

m + t(m) - diag(diag(m))

Note

m <- matrix(c(0, 5, 9, 13, 0, 0, 10, 14, 0, 0, 0, 15, 0, 0, 0, 0), 4)
m
##      [,1] [,2] [,3] [,4]
## [1,]    0    0    0    0
## [2,]    5    0    0    0
## [3,]    9   10    0    0
## [4,]   13   14   15    0

If we are starting with a data frame DF then use as.matrix to convert it first.

DF <- structure(list(V1 = c(0, 5, 9, 13), V2 = c(0, 0, 10, 14), V3 = c(0, 
0, 0, 15), V4 = c(0, 0, 0, 0)), class = "data.frame", row.names = c(NA, 
-4L))
m <- as.matrix(DF)
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • I can't get my .csv file to upload to give me an output matrix that looks like the correct m, for some reason I have mix of integers and numeric, when my csv file is as simple as the m output example you gave – twhitney Jan 09 '20 at 21:16
  • Have added to the example in the Note showing a data frame starting point. – G. Grothendieck Jan 10 '20 at 17:29