# Generating a simulated dataset from a correlation matrix with means and standard deviations [duplicate]

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?

• 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. Aug 3, 2015 at 11:56

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

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


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.

$$\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.