5
$\begingroup$

I'm trying to generate correlated data (preferably multinormal) with predefined correlations (e.g. 0.35 or 0.9). Any idea how I can do it? I'm using R and I did find a way to generate this (using mvrnorm), but you need to supply a covariance matrix. I have a covariance matrix with correlations around 0.9; however, I don't know how I can modify its entries to change the correlation. If I can do that, I'll be able to generate correlated data with the correlations I need.

Regards,

$\endgroup$
12
  • $\begingroup$ You just need to play with the values in the covariance matrix in mvrnorm and relate them with the definition of correlation matrix. $\endgroup$
    – user10525
    Commented Apr 23, 2012 at 12:00
  • 1
    $\begingroup$ If you post the code for you covariance matrix we can tell you how to modify it to get other correlations. $\endgroup$
    – MånsT
    Commented Apr 23, 2012 at 12:11
  • $\begingroup$ Procrastinator, I can't just change the values in the matrix to whatever I want, changing any number has an effect on other entries in the matrix and I must know how the other entries change (inc. or dec.) before changing anything. For example, changing the variance of any variable will change its covaraince with the other variables. $\endgroup$
    – Jawad
    Commented Apr 23, 2012 at 12:30
  • 2
    $\begingroup$ The correlation between $X_i$ and $X_j$ is given $$ Cor(X_i,X_j) = \frac{Cov(X_i, X_j)}{sd(X_i)sd(X_j)}. $$ If your correlation matrix is V this is $$ Cor(X_i,X_j) = \frac{V_{ij}}{\sqrt{V_{ii}}\sqrt{V_{jj}}}. $$ Maybe this can help you set up your covariance matrix, especially if you are able to simplify your problem by standardizing each variable. $\endgroup$
    – Erik
    Commented Apr 23, 2012 at 13:25
  • 2
    $\begingroup$ This question has been discussed on here before. For example, look here: stats.stackexchange.com/questions/13382/… $\endgroup$
    – Macro
    Commented Apr 23, 2012 at 14:52

2 Answers 2

4
$\begingroup$

Actually this is a trap question: it sounds easy but it is not (+1). The short answer to your question is you can't.

I will give an example. Imagine you have 3 Gaussian variables $X_1, X_2$ and $X_3$. You want the correlation between $X_1$ and $X_2$ to be 0, and all correlations with $X_3$ to be 1. This is obviously impossible because $X_1 = X_3$ and $X_3 = X_1$ says that $X_1 = X_2$ (up to shifting and scaling), which contrasts with the assumption that they are independent!

You would have the same situation if you replace 0 by "close to 0" and 1 by "close to 1" in the previous example. The issue here is that not every matrix is a correlation matrix. The requirement for being a correlation matrix is to be symmetric and positive definite.

You cannot choose arbitrary correlation values, but you can check whether they define a valid correlation matrix. Say that you have a symmetric square matrix mat with required correlation coefficients. You can test that it is positive definite as shown below.

all(eigen(mat)$values >= 0)

For symmetric real matrices, positive definite is equivalent to having all eigenvalues positive.

$\endgroup$
4
  • $\begingroup$ It might be good to make the inequality in the code nonstrict to allow for perfect correlations between linear combinations of variables. $\endgroup$
    – cardinal
    Commented Jun 3, 2012 at 14:41
  • $\begingroup$ @cardinal Done. But that is purely for demonstration purposes. Testing strict equality of real numbers is something R cannot do as (.3-.2) == (.2-.1) shows. $\endgroup$
    – gui11aume
    Commented Jun 3, 2012 at 14:47
  • 1
    $\begingroup$ Good point; it was actually the larger conceptual point I was trying to address. That "limitation" has more to do with floating point representation, than R itself, though. Testing against zero is a bit special. Some related routines in R will truncate small values to zero if they fall below a tolerance. $\endgroup$
    – cardinal
    Commented Jun 3, 2012 at 14:54
  • 1
    $\begingroup$ @cardinal 'That "limitation" has more to do with floating point representation, than R itself, though' Yes of course. Apologies to the R team :-) $\endgroup$
    – gui11aume
    Commented Jun 3, 2012 at 15:01
3
$\begingroup$

The MASS package has a function called mvrnorm() that can generate a group or random numbers to a specified level of correlation. An example of the setup can be found in the beginning of the example here: http://menugget.blogspot.de/2011/11/propagation-of-error.html

$\endgroup$
4
  • $\begingroup$ Sorry, didn't see that Jawad had already pointed you to the same function. In any case, the example posted might help you understand how to set it up. $\endgroup$ Commented Apr 23, 2012 at 12:47
  • $\begingroup$ Thanks Marc, from the page I understand that all I have to do is set the diagonal elements of my covariance matrix to rho and the off-diagonal elements to 1 and I should get the data I need correlated by rho? $\endgroup$
    – Jawad
    Commented Apr 23, 2012 at 13:16
  • $\begingroup$ Not exactly - the covariance matrix will depend on your defined standard deviations. If sd=1 for all series, then you are correct. Otherwise, you will need to define your std. devs for each series. $\endgroup$ Commented Apr 23, 2012 at 13:26
  • $\begingroup$ No. The variances of the variables should be along the diagonal and the off-diagonal elements should be rho (if $\sigma^2=1$). $\endgroup$
    – MånsT
    Commented Apr 23, 2012 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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