5
$\begingroup$

I have a standard correlation matrix from an academic paper with means and standard deviations:

     mean sd   var1 var2 var3
var1 4.23 1.23 1.00 
var2 3.01 0.92 0.78 1.00
var3 2.91 1.32 0.23 0.27 1.00

How can I generate a simulated dataset with a specific N (e.g. 212) using R?

$\endgroup$
1
  • $\begingroup$ See the mvrnorm function in MASS. In more general math terms this question has been answered several times on the forum (see the Related questions on the right hand side of the page). I'm voting this as a duplicate of this one, although I'm sure there are other candidates. $\endgroup$
    – Andy W
    Commented Aug 3, 2015 at 11:56

2 Answers 2

12
$\begingroup$

You can use the function mvrnorm from the MASS package to sample values from a multivariate normal distrbution.

Your data:

mu <- c(4.23, 3.01, 2.91)
stddev <- c(1.23, 0.92, 1.32)

corMat <- matrix(c(1, 0.78, 0.23,
                   0.78, 1, 0.27,
                   0.23, 0.27, 1),
                 ncol = 3)
corMat
#      [,1] [,2] [,3]
# [1,] 1.00 0.78 0.23
# [2,] 0.78 1.00 0.27
# [3,] 0.23 0.27 1.00

Create the covariance matrix:

covMat <- stddev %*% t(stddev) * corMat
covMat
#          [,1]     [,2]     [,3]
# [1,] 1.512900 0.882648 0.373428
# [2,] 0.882648 0.846400 0.327888
# [3,] 0.373428 0.327888 1.742400

Sample values. If you use empirical = FALSE, the means and covariance values represent the population values. Hence, the sampled data-set most likely does not match these values exactly.

set.seed(1)
library(MASS)
dat1 <- mvrnorm(n = 212, mu = mu, Sigma = covMat, empirical = FALSE)
colMeans(dat1)
# [1] 4.163594 2.995814 2.835397
cor(dat1)
#           [,1]      [,2]      [,3]
# [1,] 1.0000000 0.7348533 0.1514836
# [2,] 0.7348533 1.0000000 0.2654715
# [3,] 0.1514836 0.2654715 1.0000000

If you sample with empirical = TRUE, the properties of the sampled data-set match means and covariances exactly.

dat2 <- mvrnorm(n = 212, mu = mu, Sigma = covMat, empirical = TRUE)
colMeans(dat2)
# [1] 4.23 3.01 2.91
cor(dat2)
#      [,1] [,2] [,3]
# [1,] 1.00 0.78 0.23
# [2,] 0.78 1.00 0.27
# [3,] 0.23 0.27 1.00
$\endgroup$
1
$\begingroup$

Assuming normality, you could draw samples from Multivariate Normal distribution. What you need for that is a vector of means $\boldsymbol{\mu} = (\mu_1, ..., \mu_k)$ and a covariance matrix $\boldsymbol{\Sigma}$. If you recall that covariance matrix has variances on the diagonal and values of covariance in the rest of cells, you can re-create if from your data.

Correlation is

$$ \mathrm{corr}(X,Y) = \frac{\mathrm{cov}(X,Y)}{\sigma_X \sigma_Y} $$

and you already have both the correlation coefficients and standard deviations of individual variables, so you can use them to create covariance matrix. Now, you just have to use those values as parameters of some function from statistical package that samples from MVN distribution, e.g. mvtnorm package in R.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.