Marishka Usacheva - 6 months ago 72

R Question

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`

Answer

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.