Marishka Usacheva - 8 days ago 7x
R Question

# Conversion between covariance matrix and correlation matrix

I have a correlation matrix

``````cor.mat <- structure(c(1, -0.25, 0.11, 0.25, 0.18, -0.25, 1, -0.14, -0.22,
-0.15, 0.11, -0.14, 1, 0.21, 0.19, 0.25, -0.22, 0.21, 1, 0.53,
0.18, -0.15, 0.19, 0.53, 1), .Dim = c(5L, 5L))
``````

I also have a matrix of standard errors

``````sd <- structure(c(0.33, 0.62, 1, 0.54, 0.47), .Dim = c(1L, 5L))

dim(cor.mat)
#[1] 5 5
dim(sd)
#[1] 1 5
is.matrix(cor.mat)
#[1] TRUE
is.matrix(sd)
#[1] TRUE

cov.mat <-cor2cov(cor.mat, sd)
# Error in sds * R : non-conformable arrays
``````

So, the matrices have compatible dimensions, why doesn't
`cor2cov`
function work for me?

OK, I don't know where your `cor2cov` comes from. But actually, it is really straightforward to obtain covariance matrix from correlation matrix and standard errors:

``````cov.mat <- sweep(sweep(cor.mat, 1L, sd, "*"), 2L, sd, "*")

#          [,1]      [,2]    [,3]      [,4]      [,5]
#[1,]  0.108900 -0.051150  0.0363  0.044550  0.027918
#[2,] -0.051150  0.384400 -0.0868 -0.073656 -0.043710
#[3,]  0.036300 -0.086800  1.0000  0.113400  0.089300
#[4,]  0.044550 -0.073656  0.1134  0.291600  0.134514
#[5,]  0.027918 -0.043710  0.0893  0.134514  0.220900
``````

Yes, it is just a symmetric row & column rescaling.

We can verify this by transforming this covariance matrix back to correlation matrix using `cov2cor`, which is exactly your correlation matrix:

``````all.equal(cov2cor(cov.mat), cor.mat)
# [1] TRUE
``````

My guess on your `cor2cov`

If you read How to rescale a matrix by row / column, you will see there are lots of different ways for rescaling. The `sweep` used above is just one option.

R base function `cov2cor(V)` is using:

``````Is <- sqrt(1/diag(V))    ## inverse of square root diagonal (inverse of sd)
Is * V * rep(Is, each = p)
``````

I think your `cor2cov(R, sds)` is written in the same style:

``````sds * R * rep(sds, each = p)    ## `sd` must be a vector
``````

If so, `sd` must be a vector, otherwise `"*"` will complain (note, the error message you got is indeed reported from `"*"`).

Your argument "the matrices have compatible dimensions" is a bogus one. Purely in terms of linear algebra, you need `sd` to be a diagonal matrix, so that you can do:

``````sd %*% cor.mat %*% sd
``````

But row / column rescaling is never done by matrix computations as this is too expensive.