You can simply rescale the data.
n <- 100
x <- rnorm(n)
x <- ( x - mean(x) ) / sd(x)
mean(x) # 0, up to machine precision
sd(x) # 1
You could also use ppoints
to have evenly-spaced points
(you still have to rescale, though).
x <- qnorm( ppoints(n) )
x <- ( x - mean(x) ) / sd(x)
mean(x)
sd(x)
In higher dimension, the transformation is a bit trickier.
If x
is a Gaussian vector, with mean zero and variance the identity matrix,
then C %*% x
is Gaussian, with zero mean, and variance matrix V = CC'
.
C
is the Cholesky transform of V
;
it can be seen as an analogue of the square root for
(symmetric, positive semi-definite) matrices.
Two of those transformations are actually needed:
the first one to set the variance to the identity, the second to set it to the desired value.
# Desired variance matrix
V <- matrix( c(1,.2,.2, .2,1,.2, .2,.2,1), 3, 3 )
# Random data
n <- 100
k <- 3
x <- matrix( rnorm(k*n), nc=3 )
# Set the mean to 0, and the variance to the identity
x <- t( t(x) - colMeans(x) )
colMeans(x) # 0
C1 <- chol(var(x))
x <- x %*% solve(C1)
var(x) # identity matrix
# Set the variance to the desired value
C2 <- chol(V)
x <- x %*% C2
var(x) - V # zero