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)
#> NULLThe 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"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 103d_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.00d_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 98d_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] 2d_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)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)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.93You can request several at once,
e.g. complexity = c("na", "outliers"):
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