如何先生成不相关变量,再将其转化为指定相关性的变量?
Got it, let's walk through how to take your uncorrelated normal variables and transform them to have the exact correlations you want. Here's a step-by-step breakdown that builds on your existing code:
Step 1: Start with your uncorrelated variables
First, let's confirm your initial code generates uncorrelated standard normals:
# Generate 1000 uncorrelated standard normal observations for each variable a <- rnorm(1000) b <- rnorm(1000) c <- rnorm(1000) x <- matrix(c(a, b, c), ncol = 3) # Check initial correlations (should be close to 0) cor(x)
Step 2: Define your target correlation matrix
Next, create a matrix representing the correlations you want between each pair of variables:
# Desired correlation matrix (rows/columns correspond to a, b, c) target_cor <- matrix( c(1, 0.4, 0.3, # Correlations for a with a, b, c 0.4, 1, 0.5, # Correlations for b with a, b, c 0.3, 0.5, 1), # Correlations for c with a, b, c nrow = 3, ncol = 3 )
Step 3: Use Cholesky decomposition to transform the variables
The key here is using the Cholesky decomposition of your target correlation matrix. This breaks down the correlation matrix into a lower triangular matrix L such that L %*% t(L) = target_cor. Multiplying your uncorrelated variables by L will give you variables with the desired correlation structure:
# Compute Cholesky decomposition of the target correlation matrix L <- chol(target_cor) # Transform the uncorrelated variables # We transpose twice to ensure matrix multiplication works correctly (rows = observations, columns = variables) transformed_x <- t(L %*% t(x)) # Rename columns for clarity colnames(transformed_x) <- c("a_transformed", "b_transformed", "c_transformed")
Step 4: Verify the result
Finally, check that the transformed variables have the correlations you wanted:
# Check correlations of the transformed variables cor(transformed_x)
You should see values very close to your target (0.4, 0.3, 0.5) — minor differences are due to random sampling.
Note on non-normal variables
If you were starting with uniform variables instead of normals, you’d first need to convert them to standard normals using the inverse normal CDF:
# Example for uniform variables a_unif <- runif(1000) a_norm <- qnorm(a_unif) # Convert uniform to standard normal
Then follow the same steps above, since this transformation method relies on the variables being multivariate normal.
内容的提问来源于stack exchange,提问作者rook1996

