The longitudinal and multilevel simulators generate nested and
time-structured data with known generating parameters: VAR(1) multilevel
time series for mlVAR / RI-CLPM, two-level (cluster-nested) data with a
target intraclass correlation, and linear latent growth-curve
trajectories. Each returns a saqr_sim object with
$data and the true $params.
simulate_longitudinal()Generate multilevel time-series data (a VAR(1) process with temporal, contemporaneous, and between-person layers) suitable for testing mlVAR, RI-CLPM, latent growth, and similar longitudinal models.
Signature
args(simulate_longitudinal)
#> function (n = 50L, tp = 50L, vars = 4L, temporal = NULL, contemporaneous = NULL,
#> between = NULL, grand_means = NULL, innovation_sd = 1, beeps_per_day = NULL,
#> ar_range = c(0.2, 0.5), cross_range = c(0.05, 0.2), n_cross = NULL,
#> complexity = "clean", seed = NULL)
#> NULLExample
# 30 subjects, 60 time points, 3 variables
r <- simulate_longitudinal(n = 30, tp = 60, vars = 3, seed = 42)
head(r$data)r$params$temporal # the true VAR(1) matrix
#> V1 V2 V3
#> V1 0.47444181 0.0000000 0.0000000
#> V2 0.16048825 0.4811226 0.0000000
#> V3 -0.07019999 0.1485488 0.2858419
# Explicit temporal structure
B <- matrix(c(0.4, 0.0, 0.1,
0.2, 0.3, 0.0,
0.0, -0.1, 0.5), nrow = 3, byrow = TRUE)
r2 <- simulate_longitudinal(n = 50, tp = 100, vars = 3, temporal = B, seed = 1)
str(r2$params, max.level = 1)
#> List of 8
#> $ temporal : num [1:3, 1:3] 0.4 0.2 0 0 0.3 -0.1 0.1 0 0.5
#> ..- attr(*, "dimnames")=List of 2
#> $ contemporaneous: num [1:3, 1:3] 1 0 0 0 1 0 0 0 1
#> ..- attr(*, "dimnames")=List of 2
#> $ between : num [1:3, 1:3] 1 0 0 0 1 0 0 0 1
#> ..- attr(*, "dimnames")=List of 2
#> $ grand_means : Named num [1:3] 0 0 0
#> ..- attr(*, "names")= chr [1:3] "V1" "V2" "V3"
#> $ innovation_sd : Named num [1:3] 1 1 1
#> ..- attr(*, "names")= chr [1:3] "V1" "V2" "V3"
#> $ n : int 50
#> $ tp : int 100
#> $ var_names : chr [1:3] "V1" "V2" "V3"simulate_mlm()Generate two-level data where level-1 units are nested within
clusters, with a target intraclass correlation and a fixed slope on the
first predictor (and an optional cluster random slope), designed so both
are recovered at large n_clusters. The core example below
does not require lme4; an optional fit is shown
afterwards.
Signature
args(simulate_mlm)
#> function (n_clusters = 30, cluster_size = 20, intercept = 0,
#> slope = 0.5, residual_sd = 1, icc = 0.1, n_predictors = 1,
#> random_slope = FALSE, slope_sd = 0, seed = NULL)
#> NULLExample
r <- simulate_mlm(n_clusters = 40, cluster_size = 25, slope = 0.8,
icc = 0.2, seed = 1)
print(r)
#> saqr_sim [mlm] 1000 x 3 (seed=1)
#> params: intercept, slope, betas, icc, tau00, residual_sd, slope_sd, random_slope, cluster_size, cluster_intercepts, cluster_slopes
#> cols: cluster_id, y, x1
head(r$data)str(r$params)
#> List of 11
#> $ intercept : num 0
#> $ slope : num 0.8
#> $ betas : Named num 0.8
#> ..- attr(*, "names")= chr "x1"
#> $ icc : num 0.2
#> $ tau00 : num 0.25
#> $ residual_sd : num 1
#> $ slope_sd : num 0
#> $ random_slope : logi FALSE
#> $ cluster_size : Named int [1:40] 25 25 25 25 25 25 25 25 25 25 ...
#> ..- attr(*, "names")= chr [1:40] "cluster_1" "cluster_2" "cluster_3" "cluster_4" ...
#> $ cluster_intercepts: Named num [1:40] -0.3132 0.0918 -0.4178 0.7976 0.1648 ...
#> ..- attr(*, "names")= chr [1:40] "cluster_1" "cluster_2" "cluster_3" "cluster_4" ...
#> $ cluster_slopes : NULLsimulate_growth()Generate longitudinal data from a linear latent growth-curve model:
each subject draws a random intercept and slope from a bivariate normal,
then \(y_{it} = b_{0i} + b_{1i}\,t +
e_{it}\) with time coded
0..(n_time - 1). Returned in long format.
Signature
args(simulate_growth)
#> function (n = 200, n_time = 5, intercept_mean = 0, slope_mean = 1,
#> intercept_sd = 1, slope_sd = 0.5, intercept_slope_cor = 0,
#> residual_sd = 1, seed = NULL)
#> NULLExample
r <- simulate_growth(n = 300, n_time = 6, slope_mean = 2,
intercept_sd = 1.5, seed = 1)
print(r)
#> saqr_sim [growth] 1800 x 3 (seed=1)
#> params: means, sds, correlation, residual_sd, n_time, subject_intercepts, subject_slopes
#> cols: subject, time, y
head(r$data)str(r$params)
#> List of 7
#> $ means : Named num [1:2] 0 2
#> ..- attr(*, "names")= chr [1:2] "intercept" "slope"
#> $ sds : Named num [1:2] 1.5 0.5
#> ..- attr(*, "names")= chr [1:2] "intercept" "slope"
#> $ correlation : num 0
#> $ residual_sd : num 1
#> $ n_time : int 6
#> $ subject_intercepts: Named num [1:300] -0.94 0.275 -1.253 2.393 0.494 ...
#> ..- attr(*, "names")= chr [1:300] "s1" "s2" "s3" "s4" ...
#> $ subject_slopes : Named num [1:300] 2.45 1.48 2.99 1.81 2.83 ...
#> ..- attr(*, "names")= chr [1:300] "s1" "s2" "s3" "s4" ...d <- r$data
ids <- head(unique(d$subject), 8)
sub <- d[d$subject %in% ids, ]
plot(sub$time, sub$y, type = "n",
xlab = "time", ylab = "y",
main = "simulate_growth(): individual trajectories")
invisible(lapply(split(sub, sub$subject), function(s) {
s <- s[order(s$time), ]
lines(s$time, s$y, col = as.integer(factor(s$subject[1], levels = ids)), lwd = 2)
}))Trajectories of a few subjects.