# Generate value of variables for given correlation coefficient

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

cor(1:1000,(1:1000)^8.8)

#0.4 ---> r = 0.39918

cor(1:1000,(1:1000)^34.11)

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

cor(1:1000,sin(100*(1:1000))^9)


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.

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

library(MASS)
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])
 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)
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.

• 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? – whuber Mar 14 '19 at 18:36
• @whuber, I tried to do so, but my intuition regarding the SVD is limited. – Christoph Hanck Mar 15 '19 at 9:28