Context

Sometimes it is useful to make a small dataset where the numbers come out exactly in an analysis. This function generates such a dataset. It is not to be used to generate simulated data to investigate the sampling behavior of statistics and parameters in an analysis

Define Function to generate simulated correlated data

# --- Settings ---
simulate_correlated_data <- function(var_names, n, cor_matrix, means, sds, seed = NULL) {
  if (!is.null(seed)) set.seed(seed)

  LK <- length(var_names)

  # --- Checks ---
  if (!is.matrix(cor_matrix) || nrow(cor_matrix) != LK || ncol(cor_matrix) != LK) {
    stop("cor_matrix must be a square matrix with dimensions equal to the number of variables.")
  }
  if (length(means) != LK || length(sds) != LK) {
    stop("Length of means and sds must match the number of variables.")
  }

  # --- Step 1: Generate standard normal data ---
  V <- matrix(rnorm(n * LK), nrow = n, ncol = LK)

  # --- Step 2: Whiten data to mean 0 and uncorrelated ---
  V_centered <- scale(V, center = TRUE, scale = FALSE)
  svd_decomp <- svd(t(V_centered) %*% V_centered)
  U <- svd_decomp$u
  M <- svd_decomp$d
  V_white <- V_centered %*% U %*% diag(1 / sqrt(M)) * sqrt(n)

  # --- Step 3: Impose desired correlation structure ---
  eig_corr <- eigen(cor_matrix)
  L_corr <- eig_corr$vectors %*% diag(sqrt(eig_corr$values))
  V_final <- V_white %*% t(L_corr)

  # --- Step 4: Scale and shift to desired means and SDs ---
  for (i in 1:LK) {
    V_final[, i] <- V_final[, i] * sqrt((n - 1) / n) * sds[i] + means[i]
  }

  colnames(V_final) <- var_names
  return(as.data.frame(V_final))
}

Sample Usage

Assuming the varibles are named a through f, with the following means and standard deviations for a sample size of 100

# Parameters
var_names <- c("a", "b", "c", "d", "e", "f")
n <- 100
means <- c(0, 1, 2, 3, 4, 5)
sds   <- c(1, 2, 3, 4, 5, 6)

cor_matrix <- matrix(c(
  1.000, -0.273,  0.400,  0.523,  0.023,  0.188,
 -0.273,  1.000, -0.106, -0.262,  0.033, -0.178,
  0.400, -0.106,  1.000,  0.492, -0.029,  0.125,
  0.523, -0.262,  0.492,  1.000, -0.272,  0.234,
  0.023,  0.033, -0.029, -0.272,  1.000, -0.074,
  0.188, -0.178,  0.125,  0.234, -0.074,  1.000
), nrow = 6, byrow = TRUE)

# Simulate dataset
df_sim <- simulate_correlated_data(var_names, n, cor_matrix, means, sds, seed = 123)

# Check result
summary(df_sim)
##        a                  b                 c                 d          
##  Min.   :-3.10967   Min.   :-3.7994   Min.   :-4.3887   Min.   :-6.1599  
##  1st Qu.:-0.57506   1st Qu.:-0.3009   1st Qu.: 0.2321   1st Qu.: 0.4108  
##  Median : 0.02512   Median : 0.7698   Median : 1.6151   Median : 3.0675  
##  Mean   : 0.00000   Mean   : 1.0000   Mean   : 2.0000   Mean   : 3.0000  
##  3rd Qu.: 0.65243   3rd Qu.: 2.1168   3rd Qu.: 4.2584   3rd Qu.: 5.9943  
##  Max.   : 1.92669   Max.   : 5.9309   Max.   : 8.7695   Max.   :12.1346  
##        e                f          
##  Min.   :-7.391   Min.   :-15.211  
##  1st Qu.: 0.521   1st Qu.:  0.999  
##  Median : 3.605   Median :  5.927  
##  Mean   : 4.000   Mean   :  5.000  
##  3rd Qu.: 7.698   3rd Qu.:  8.452  
##  Max.   :15.651   Max.   : 16.482
cor(df_sim)
##        a      b      c      d      e      f
## a  1.000 -0.273  0.400  0.523  0.023  0.188
## b -0.273  1.000 -0.106 -0.262  0.033 -0.178
## c  0.400 -0.106  1.000  0.492 -0.029  0.125
## d  0.523 -0.262  0.492  1.000 -0.272  0.234
## e  0.023  0.033 -0.029 -0.272  1.000 -0.074
## f  0.188 -0.178  0.125  0.234 -0.074  1.000
data.frame(
  Mean = round(sapply(df_sim, mean, na.rm = TRUE), 2),
  SD   = round(sapply(df_sim, sd, na.rm = TRUE), 2)
)
##   Mean SD
## a    0  1
## b    1  2
## c    2  3
## d    3  4
## e    4  5
## f    5  6

Show created data frame V-final

print(df_sim)
##                a            b          c            d           e            f
## 1   -0.093070313  3.941648595  4.5880724  4.385073862  2.57279231  14.09032077
## 2   -0.611852034  5.071148676  1.2527659  1.692132423  1.57984689   5.65906307
## 3   -1.269668132 -0.280557397  2.0558166  3.870441988 -2.70464946   0.89424510
## 4   -0.107886716  0.954530879  3.7359260  7.019836175 -0.44614470   6.60738334
## 5    0.351480935  0.545548598 -1.3146288  0.379711392  2.61862661  11.78551335
## 6   -2.162225105  1.428804680 -1.2786144 -2.108706641  2.87768707  -2.63994107
## 7   -0.261045176  1.013433467 -2.4847226  3.555123706 -4.98873775   8.42102339
## 8    0.863036706  1.001554194 -3.0795021  1.583292563  8.52348999  16.48174460
## 9   -0.588874162  3.205250885  4.5053856  3.101519215 11.33992973   7.00544562
## 10   0.402483461  1.334530419  2.5016313 -0.001463991 13.73717815  -1.54816290
## 11  -0.711680473 -0.653775773  2.5372310 -1.667635327  7.97609192   5.30464761
## 12   0.056507617  0.879954136  3.4605901  1.267514954  6.62289638   0.74946551
## 13  -0.194324198 -0.153220579  5.5352748  8.752478289 -3.61282644  15.60300045
## 14  -0.006274282  0.526236585  0.7464423  4.527876106  1.43768220   3.14646616
## 15   0.409891474  1.816818232 -1.7499859  3.007136898  3.68571962   0.61659412
## 16  -3.109670072  5.437920395  1.0598571 -5.318928763  4.47797132  -1.43652791
## 17  -0.206120095  0.633202117  0.6101579  1.747706941  2.87422311   2.18758888
## 18   1.453253243  0.599170977  0.4277633 11.413742723  2.58740913   9.45433319
## 19  -0.326276872 -1.221723901 -1.9751310 -3.342159421 10.91024633   5.42192075
## 20  -0.501169978  0.002639407 -2.5231355  2.883823383  9.85760582   4.40338243
## 21   1.926688268 -1.689024405  4.4129608  8.388992053  6.87090130   5.63660501
## 22  -0.269057692  0.757742385  2.7939657  2.017806912 10.53132411   9.22750520
## 23   0.634727211  3.225319270  2.3955305  6.264273129  0.55298501  12.64697501
## 24   1.090701916  0.734295774  4.2387527  3.514070697  8.52636566  10.00875840
## 25   0.508762724  2.286638183  2.7348659  7.122826678  2.27266070  -7.27448403
## 26   0.181822944  1.667917753  1.5795283  7.815668542 10.83632560   6.16771238
## 27   1.458807717 -3.799362787  5.7836136  5.219427658  1.75777934   4.11983471
## 28  -0.067425262  0.054592996  0.6453739  2.115901763  6.77349661   1.03389933
## 29   1.144666903 -0.427105783  5.8364489  5.777598106 12.48346861  12.94515010
## 30  -1.607010955  1.353362866 -3.0236525 -1.610387127  2.33765834  -1.54981915
## 31  -0.314781543  3.294233810  7.5652174  0.899582014  7.28720233  -1.49511793
## 32   0.870546967  1.688090992  1.2517118  4.312260547 -0.65895667   5.16092550
## 33  -0.024074056  1.781430305  0.3088724 -1.541198645 -0.50548836   7.13326130
## 34  -1.550930533  0.269883312 -0.8039703 -1.073868085  9.77652149  -0.86739732
## 35  -1.275598979 -3.123097345  2.8199634  7.328963309  5.16575799   7.68789763
## 36  -0.311020772  0.997021618 -0.6075213  6.206950753 -6.55974931  -5.97246955
## 37  -0.086882748 -1.971589705  3.3162740  8.553741528 -2.39584948  11.00296306
## 38   1.080811319  0.523428211  5.0171881  4.403485408  2.92571350   3.73553953
## 39  -0.976195246  5.782646372 -0.4178888 -1.185698388  8.29772409  -8.76666136
## 40   0.768658560 -1.671225300  0.5129775  5.092122715  5.04568271  12.58195199
## 41  -0.296024052  2.708325225 -1.6501602  2.240503244  8.31336869  -3.22565318
## 42   0.302784101  0.219020546  0.4573969  1.111381700  9.05615793   5.02467243
## 43   0.108873744  0.680163009  5.9699975  6.408035101 14.64187758  14.03883264
## 44  -1.619069968 -1.177224820 -3.3372439 -4.244815483  1.36673155   7.56188496
## 45  -1.719424441 -0.890782173  1.2374299  3.683404273  2.56181580   6.78347237
## 46   0.562512035  2.770280474  6.5826661 11.422729650 -1.29029057  12.66018010
## 47   0.128022969  0.757297279 -0.7748102  1.835949305  6.25147400  13.66463822
## 48   1.390517461 -1.024851672  1.3768876  6.857722015  2.07607088   0.18599109
## 49  -1.142465010  1.781116801  2.8592717  7.603107584 -2.41389895 -15.21138929
## 50  -1.617238990  3.169566854 -1.1349026  2.545640176  4.62060718   8.31390952
## 51   1.038322517 -1.492105075  4.8820416  3.040213051  7.60503807   0.08796974
## 52   1.561618869  0.868309523  0.8280427  4.299531283 -4.97516702   5.36307283
## 53   0.515360404 -0.392617148  3.5605541  6.934500446  2.10753727   1.52834307
## 54  -0.588551333 -1.390129836  2.9714891  1.302007685  2.55474534   8.39590180
## 55   0.621365770  0.483251181  8.7694754  9.934377343  0.42508923   8.63520167
## 56  -2.848132809  4.117190000 -4.2480011 -5.500164190  3.71944368  -0.66193986
## 57   1.678402012  2.203656017  5.4530795  5.852782620  8.57222722   7.51919663
## 58  -0.831782406  2.136765567  1.4081805  0.486547201  3.37116997   6.17123021
## 59   0.922294378  1.899751361  1.7244423  5.923460232 -7.39125043   2.94850380
## 60  -0.673352291 -0.473623102 -2.7136885 -3.121746557 15.65084860  -0.43956313
## 61   0.996937383  0.758665435  1.0681319 -0.081371786  2.11549363   1.30813921
## 62  -0.446290984 -0.021052739  0.6084907  5.486121337  8.63207291   5.77022109
## 63   0.164798589  0.780963955 -0.0273997  1.550912650  6.77258248  12.78615094
## 64   0.957175640  4.178252714  8.1592720  5.452043619  9.12515053 -11.35175714
## 65  -0.720177170  5.930924025  2.7385792  0.914901281 10.47346790  10.31272656
## 66   0.705541443  1.241367307  6.9082280  3.111612362  2.40672774   8.43309677
## 67   0.464934281 -0.285360590  3.8156773  2.701433393  4.63665096   0.74924420
## 68   1.451099082 -3.378666949  0.9630514  7.187389711 -0.15455980   6.55392436
## 69  -0.332357712  0.482159337  1.0864137 -1.589865772  6.15666178  -0.51661016
## 70  -0.047411391 -1.115938531  4.0623987 -0.623663385 -2.00352131   3.31241214
## 71   1.092950390 -1.435645742  7.8080348  3.498868178 15.59715847   7.40875822
## 72   1.340365918  5.403773653  0.3340669  7.284807580  1.48171291  11.84600934
## 73  -1.483386005  3.418714232  0.1949640 -0.945553755  0.68322533   3.30076208
## 74   0.964729517  1.343917549  0.2445051  2.894885286  8.31305043  -9.85488320
## 75  -0.201446597  2.414969682  1.9889216  3.115761730  8.29732640   9.51342567
## 76  -0.753006863 -1.964003919  2.7600321  6.291479025  0.07066451   5.76742051
## 77   1.572636710 -0.896326051  5.3202636  7.809962955 -0.01586151   8.50753710
## 78   0.491270686  2.399828154  1.5442540  5.702151763  7.13932980   3.02626198
## 79   0.410068216  2.558742731  0.8933837 -1.552351366  3.79478656   6.03001310
## 80   0.061440997  1.462864955  0.9969283  6.852556083 -3.15629234   7.82373225
## 81  -0.128016687 -1.095185473 -2.8217721  3.094790042  4.98700024   5.82465628
## 82   0.370103626  2.127714430  4.3174829  0.830238018  3.77031182   0.07414489
## 83   1.098442108  0.921735657  2.0934825  1.132620430  5.83389420  11.53174622
## 84  -0.366920074 -0.526830162  1.6506572  5.435774720 -1.28380429   7.39278505
## 85   0.563374160  1.159739740  1.0888393  0.421103114  6.93571744   8.30228652
## 86   0.110943676 -0.074715988  2.7988418 -0.216171785  9.78450025   5.34816242
## 87   0.368185646 -0.092158011  4.9270288  0.321665660  3.52384913  -0.79501069
## 88  -0.570561495  4.094317944  3.0431982  1.599817318 -1.43072591   7.88921806
## 89   1.739250234 -0.730135174  4.7161819  6.224327517  2.24976349   3.76672854
## 90  -1.052510494  1.715275804 -0.6397490 -3.486224531  4.13594958   6.23346091
## 91  -0.350054833  4.451562302 -0.4300714 -5.975582127 -0.20676688   9.47163082
## 92   0.875323349  0.002785507  6.1777458  7.337219827 -6.50443173  12.10492405
## 93   0.536014357 -0.197893838  7.4296283  3.612636431  7.39278609   6.29351675
## 94  -0.550921455  1.934711379 -2.1233287  5.633670349  2.44508456   6.46145757
## 95  -2.021033331  2.113212638  4.9774105  2.801976974 -0.11481657  10.56700238
## 96  -0.173093685  5.108377045 -0.6247452 -2.853401376 11.56010110  -7.27927735
## 97  -0.899065814  2.095208235  6.2642459 -1.532290103 -3.58128430   4.39884106
## 98  -0.966667340 -0.763299156 -4.3886634 -6.159882372  5.97928607   7.70353677
## 99   0.329030734 -0.347454314  3.6557147  9.594831258 -0.79115122   7.48183558
## 100  0.334539662  0.053209098  7.2261206 12.134597024  4.87675174  11.78677725