I am trying to figure out how to convert a correlation matrix (R) to a covariance matrix (S) for input into a random number generator that only accepts S (rmvnorm("mvtnorm")
in R)
library("mvtnorm")
TRUTH= 0.8 # target correlation value between X1 and X2
R <- as.matrix(data.frame(c(1, TRUTH), c(TRUTH, 1)))
V <- diag(c(sqrt(1), sqrt(1))) # diagonal matrix of sqrt(variances)
S <- V %*% R %*% V
cor(rmvnorm(100, sigma=S) )
# repeat this to get an idea of the variance around Pearson's estimator
Instance where variances are not equal to 1
V <- diag(c(sqrt(3), sqrt(2)))
S <- V %*% R %*% V
cor(rmvnorm(100, sigma=S) )
This seems to be correct, but I would like expert criticism.
NewMatrix = Matrix &* (coef*t(coef))
wherecoef = sqrt(NewDiagonal/Diagonal)
,*
is vector multiplication and&*
is usual, elementwise multiplication. $\endgroup$V
had better be the diagonal matrix of square roots of variances for this to work. $\endgroup$V
. It should be obvious that this works because (1) separate linear transformations in the variables do not change their correlation but (2) rescaling a unit variance variable by a constant scales its variance by the square of that constant. Then if you look at whatmvtnorm
does behind the scenes to factorR
, you can see how it effectively carries out the same post-multiplication byV
. $\endgroup$V %*% R %*% V
is equivalent to what I've suggested above. But, I predict, your formula with two matrix multiplications is slower (which must show on big matrices). Elementwise multiplication of matrices (is there such an operation in R?) is faster, AFAIK. $\endgroup$