Reputation: 25
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?
Upvotes: 1
Views: 193
Reputation: 269586
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))
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)
Upvotes: 1
Reputation: 887118
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)]
Upvotes: 2