I want to create a correlation matrix given the correlation vector, which is the upper (or lower) triangular matrix of the correlation matrix.
The goal is to transform this vector
to this correlation matrix with 1s on the diagonal.
Do you know if there is a method creating a matrix given the triangular above the diagonal and to set the diagonal to 1?
You can convince R that your vector is a distance object then use as.matrix
to convert it:
> myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
> class(myvec) <- 'dist'
> attr(myvec,'Size') <- 4
> as.matrix(myvec)
1 2 3 4
1 0.00 -0.55 -0.48 0.66
2 -0.55 0.00 0.47 -0.38
3 -0.48 0.47 0.00 -0.46
4 0.66 -0.38 -0.46 0.00
Or a variation on the answer by @AnandaMahto (similar to the internals used above):
> myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
> mycor <- matrix(0,4,4)
> mycor[ col(mycor) < row(mycor) ] <- myvec
> mycor <- mycor + t(mycor)
> diag(mycor) <- 1
> mycor
[,1] [,2] [,3] [,4]
[1,] 1.00 -0.55 -0.48 0.66
[2,] -0.55 1.00 0.47 -0.38
[3,] -0.48 0.47 1.00 -0.46
[4,] 0.66 -0.38 -0.46 1.00
I don't know if there is an automatic way to do this, but expanding on my comment:
myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
mempty <- matrix(0, nrow = 4, ncol = 4)
mindex <- matrix(1:16, nrow = 4, ncol = 4)
mempty[mindex[upper.tri(mindex)]] <- myvec
mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
diag(mempty) <- 1
mempty
# [,1] [,2] [,3] [,4]
# [1,] 1.00 -0.55 -0.48 0.47
# [2,] -0.55 1.00 0.66 -0.38
# [3,] -0.48 0.66 1.00 -0.46
# [4,] 0.47 -0.38 -0.46 1.00
Here's a quickly hacked together function. I hope all my mathematics steps are correct!
vec2symmat <- function(invec, diag = 1, byrow = TRUE) {
Nrow <- ceiling(sqrt(2*length(invec)))
if (!sqrt(length(invec)*2 + Nrow) %% 1 == 0) {
stop("invec is wrong length to create a square symmetrical matrix")
}
mempty <- matrix(0, nrow = Nrow, ncol = Nrow)
mindex <- matrix(sequence(Nrow^2), nrow = Nrow, ncol = Nrow, byrow = byrow)
if (isTRUE(byrow)) {
mempty[mindex[lower.tri(mindex)]] <- invec
mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
} else {
mempty[mindex[upper.tri(mindex)]] <- invec
mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
}
diag(mempty) <- diag
mempty
}
Here it is with a different value for the diagonal.
vec2symmat(1:3, diag = NA)
# [,1] [,2] [,3]
# [1,] NA 1 2
# [2,] 1 NA 3
# [3,] 2 3 NA
Here's an error message if you try to provide data that can't create a square matrix.
vec2symmat(1:4)
# Error in vec2symmat(1:4) :
# invec is wrong length to create a square symmetrical matrix
And, with default settings.
vec2symmat(1:10)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 2 3 4
# [2,] 1 1 5 6 7
# [3,] 2 5 1 8 9
# [4,] 3 6 8 1 10
# [5,] 4 7 9 10 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With