I would like to generate test data for script used for correlation analysis between quite long variables.
Is it possible for a given length of vectors, to generate in relatively simple way deterministic input data that have Pearson correlation coefficient equal almost exactly given r (e.g. 0.5,0.6.,0.7, etc.) ?

In R I tried something like the following:

#0.7 ---> r = 0.691


 #0.4 ---> r = 0.39918


 #0 ---> r = 6.526891e-06 


I'm looking for a (relatively) compact formula that generates such input vectors of length $n$ for given $r$ with required precision (e.g.precision=0.000001)

To simplify problem I don't care about p-value/significance.


1 Answer 1


If what needs to be deterministic is the correlation coefficient, you may use the option empirical=T option in mvrnorm, as in

correlation.coeff <- 0.6
correlation.matrix <- matrix(c(1,correlation.coeff,correlation.coeff,1),ncol=2)
mu <- runif(2) # could be anything
x <- mvrnorm(n = 1000, empirical = TRUE, mu = mu, Sigma = correlation.matrix)

Empirical correlation is as specified:

> cor(x[,1],x[,2])
[1] 0.6

If you want the data to be reproducible, you can use set.seed(1).

Why? I stripped the code of mvrnorm of some error and robustness checks. Note mvrnorm.simple is not safe to use in general.

mvrnorm.simple <- function (n, mu, Sigma, empirical = FALSE) {
  p <- length(mu)
  eS <- eigen(Sigma, symmetric = TRUE)
  ev <- eS$values
  X <- matrix(rnorm(p * n), n)
  if (empirical) {
    X <- scale(X, TRUE, FALSE)
    X <- X %*% svd(X)$v
    X <- scale(X, FALSE, TRUE)
  X <- mu + eS$vectors %*% diag(sqrt(ev), p) %*%t(X)

So what empirical=T does is to columnwise demean the $n\times p$ matrix of standard normals to get $\tilde X$, multiply with the matrix $V$ of the singular value decomposition $\tilde X=UDV'$ to then scale each columns by its root mean square, see also ?scale.

This ensures that the random draws to which the penultimate line of the code is applied have exact (up to numerical inaccuracies) sample means and covariances of zero and variances of one.

  • $\begingroup$ It would be nice to know how this option actually works, which as presented is just an uninformative black box solution. Could you provide an explanation? $\endgroup$
    – whuber
    Commented Mar 14, 2019 at 18:36
  • $\begingroup$ @whuber, I tried to do so, but my intuition regarding the SVD is limited. $\endgroup$ Commented Mar 15, 2019 at 9:28

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.