This reference covers simulate_data(), the seed-driven random-parameter generator. Unlike the explicit-parameter simulators, it returns a bare data.frame (not a saqr_sim), and the seed determines both the random data and the structural parameters (sample size, effect sizes, number of groups/variables) — so each seed yields a structurally unique, ready-to-analyse dataset. It also supports edge-case (“complexity”) injection and batch generation.

simulate_data()

A single dispatcher over many dataset types. Each dataset carries type, info, and complexity attributes; the info attribute is the intended analysis call for that type.

Signature

args(simulate_data)
#> function (type, seed = NULL, complexity = "clean", ..., n_batch = NULL) 
#> NULL

The full catalogue of types:

.SIM_VALID_TYPES
#>  [1] "ttest"           "anova"           "correlation"     "clusters"       
#>  [5] "factor_analysis" "prediction"      "mlvar"           "probit"         
#>  [9] "meta"            "count"           "reliability"     "gam"            
#> [13] "nma"             "power"           "cthmm"

Core types

Each of these returns a bare data.frame ready for its intended analysis.

d_ttest <- simulate_data("ttest", seed = 42)
str(d_ttest)
#> 'data.frame':    78 obs. of  2 variables:
#>  $ group: Factor w/ 2 levels "A","B": 1 1 1 1 2 1 1 1 2 1 ...
#>  $ score: num  50 53.2 51.3 51 50.2 ...
#>  - attr(*, "type")= chr "ttest"
#>  - attr(*, "info")= chr "t.test(score ~ group, data = d)"
#>  - attr(*, "complexity")= chr(0)
head(d_ttest)
attributes(d_ttest)[c("type", "info", "complexity")]
#> $type
#> [1] "ttest"
#> 
#> $info
#> [1] "t.test(score ~ group, data = d)"
#> 
#> $complexity
#> character(0)
d_anova <- simulate_data("anova", seed = 42)
str(d_anova)
#> 'data.frame':    350 obs. of  2 variables:
#>  $ group: Factor w/ 3 levels "G1","G2","G3": 2 1 2 1 2 1 1 3 1 2 ...
#>  $ score: num  39.1 39.4 42.6 36 40.1 ...
#>  - attr(*, "type")= chr "anova"
#>  - attr(*, "info")= chr "summary(aov(score ~ group, data = d))"
#>  - attr(*, "complexity")= chr(0)
table(d_anova$group)
#> 
#>  G1  G2  G3 
#> 133 114 103
d_cor <- simulate_data("correlation", seed = 42)
str(d_cor)
#> 'data.frame':    350 obs. of  4 variables:
#>  $ x1: num  45.4 50.3 45.4 48.6 50.9 ...
#>  $ x2: num  35.8 16.08 -6.56 6.26 2.04 ...
#>  $ x3: num  94.7 111.2 98.2 104.5 116.8 ...
#>  $ x4: num  109 102 106 103 112 ...
#>  - attr(*, "type")= chr "correlation"
#>  - attr(*, "info")= chr "cor(d); pairs(d)"
#>  - attr(*, "complexity")= chr(0)
round(cor(d_cor), 2)
#>      x1   x2   x3   x4
#> x1 1.00 0.11 0.76 0.73
#> x2 0.11 1.00 0.10 0.11
#> x3 0.76 0.10 1.00 0.44
#> x4 0.73 0.11 0.44 1.00
d_clusters <- simulate_data("clusters", seed = 42)
str(d_clusters)
#> 'data.frame':    350 obs. of  3 variables:
#>  $ x1          : num  -5.53 -6.51 2.36 3.45 3.11 ...
#>  $ x2          : num  -0.889 -0.356 4.358 7.275 4.456 ...
#>  $ true_cluster: int  1 1 2 3 2 1 1 1 2 1 ...
#>  - attr(*, "type")= chr "clusters"
#>  - attr(*, "info")= chr "kmeans(d[, -ncol(d)], centers = max(d$true_cluster))"
#>  - attr(*, "complexity")= chr(0)
table(d_clusters$true_cluster)
#> 
#>   1   2   3 
#> 138 114  98
d_fa <- simulate_data("factor_analysis", seed = 42)
str(d_fa)
#> 'data.frame':    370 obs. of  6 variables:
#>  $ x1: num  5.32 1.64 2.75 2.9 3.67 ...
#>  $ x2: num  5.84 4.39 5.81 4.78 5.3 ...
#>  $ x3: num  1.712 1.731 2.86 0.492 3.069 ...
#>  $ x4: num  5.31 4.7 2.99 3.18 2.98 ...
#>  $ x5: num  4.18 4.68 3.84 4.13 4.09 ...
#>  $ x6: num  6.56 7.26 5.09 4.69 3.81 ...
#>  - attr(*, "n_factors")= int 2
#>  - attr(*, "loadings")= num [1:6, 1:2] 0.829 0.842 0.541 0.071 -0.11 ...
#>  - attr(*, "type")= chr "factor_analysis"
#>  - attr(*, "info")= chr "factanal(d, factors = attr(d, 'n_factors'))"
#>  - attr(*, "complexity")= chr(0)
attr(d_fa, "n_factors")
#> [1] 2
d_pred <- simulate_data("prediction", seed = 42)
str(d_pred)
#> 'data.frame':    78 obs. of  7 variables:
#>  $ y   : num  118.405 31.218 112.198 -0.768 -40.877 ...
#>  $ x1  : num  11.03 11.16 7.35 14.15 5.72 ...
#>  $ x2  : num  -0.758 0.983 -0.66 1.982 2.667 ...
#>  $ x3  : num  7.89 7.41 10.64 9.85 9.35 ...
#>  $ x4  : num  11.19 9.29 7.12 2.37 5.96 ...
#>  $ cat1: Factor w/ 3 levels "L1","L2","L3": 1 3 2 3 2 3 1 1 3 2 ...
#>  $ cat2: Factor w/ 2 levels "M1","M2": 2 1 2 2 1 2 2 1 1 2 ...
#>  - attr(*, "type")= chr "prediction"
#>  - attr(*, "info")= chr "summary(lm(y ~ ., data = d))"
#>  - attr(*, "complexity")= chr(0)
head(d_pred)

Newer types

The dispatcher also covers "probit", "count", "meta", "reliability", "gam", "nma", "power", and "cthmm". Their info attribute documents the intended analysis. ("power" returns a one-row list of inputs rather than a data frame.)

newer <- c("probit", "count", "meta", "reliability",
           "gam", "nma", "power", "cthmm")
do.call(rbind, lapply(newer, function(tp) {
  d <- simulate_data(tp, seed = 42)
  data.frame(type = tp,
             class = class(d)[1],
             intended_analysis = attr(d, "info"),
             row.names = NULL)
}))

One worked example — a Poisson count dataset, ready for glm(..., poisson):

d_count <- simulate_data("count", seed = 42)
str(d_count)
#> 'data.frame':    98 obs. of  3 variables:
#>  $ y : int  3 2 0 1 3 2 3 3 3 2 ...
#>  $ x1: num  1.5307 0.9559 0.0479 -1.1046 0.539 ...
#>  $ x2: num  -1.2143 0.6168 0.0429 -0.1439 -0.1451 ...
#>  - attr(*, "type")= chr "count"
#>  - attr(*, "info")= chr "glm(y ~ x1 + x2, data = d, family = poisson)"
#>  - attr(*, "complexity")= chr(0)
head(d_count)

Complexity (edge-case) injection

Pass complexity to inject specific edge cases for stress testing. With complexity = "na", missing values are introduced; with "outliers", extreme values are added. The injected cases are recorded in the complexity attribute.

d_na <- simulate_data("ttest", seed = 1, complexity = "na")
sum(is.na(d_na))
#> [1] 40
attr(d_na, "complexity")
#> [1] "na"
d_out <- simulate_data("prediction", seed = 1, complexity = "outliers")
attr(d_out, "complexity")
#> [1] "outliers"
summary(d_out$y)
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#> -130.83  -61.19  -38.48  -38.58  -16.82   54.93

You can request several at once, e.g. complexity = c("na", "outliers"):

d_multi <- simulate_data("ttest", seed = 1, complexity = c("na", "outliers"))
attr(d_multi, "complexity")
#> [1] "na"       "outliers"

Batch generation

Pass n_batch to get a list of structurally distinct datasets (each with its own seed) instead of a single one. In batch mode the default complexity is "auto", which randomly injects 0–3 edge cases per dataset (seed-driven, so fully reproducible).

batch <- simulate_data("ttest", seed = 1, n_batch = 20)
class(batch)
#> [1] "sim_batch_type" "list"
length(batch)
#> [1] 20
str(batch[[1]])
#> 'data.frame':    19 obs. of  2 variables:
#>  $ group: Factor w/ 2 levels "A","B": 1 2 2 2 2 1 1 2 2 1 ...
#>  $ score: num  40.6 42.6 41.9 40.8 41.9 ...
#>  - attr(*, "type")= chr "ttest"
#>  - attr(*, "info")= chr "t.test(score ~ group, data = d)"
#>  - attr(*, "complexity")= chr [1:3] "heavy_tailed" "na" "tiny_n"
#>  - attr(*, "seed")= int 7920
#>  - attr(*, "batch_id")= int 1
attr(batch[[1]], "complexity")
#> [1] "heavy_tailed" "na"           "tiny_n"

Setting type = "batch" generates a batch of every type at once:

all_batches <- simulate_data("batch", seed = 1, n_batch = 5)
class(all_batches)
#> [1] "sim_batch_full" "list"
names(all_batches)
#>  [1] "ttest"           "anova"           "correlation"     "clusters"       
#>  [5] "factor_analysis" "prediction"      "mlvar"           "probit"         
#>  [9] "meta"            "count"           "reliability"     "gam"            
#> [13] "nma"             "power"           "cthmm"
vapply(all_batches, length, integer(1))
#>           ttest           anova     correlation        clusters factor_analysis 
#>               5               5               5               5               5 
#>      prediction           mlvar          probit            meta           count 
#>               5               5               5               5               5 
#>     reliability             gam             nma           power           cthmm 
#>               5               5               5               5               5