Simulate Data From a Factorial ANCOVA Design (up to Four Factors, Any Number of Covariates)
Source:R/simulate_ancova_factorial_data.R
simulate_ancova_factorial_data.RdGenerates random data appropriate for an analysis of covariance with up to four crossed fixed factors (\(A, B, C, D\)) and one or more continuous covariates. Within every cell the outcome \(Y\) and the covariates \(X_1, \ldots, X_q\) are jointly multivariate normal with a common (homogeneous) within-cell covariance structure, the standard assumption underlying classical ANCOVA. Per-cell sample sizes may be equal or unequal.
Usage
simulate_ancova_factorial_data(
a,
b = 1,
c = 1,
d = 1,
n_covariates = 1,
mu_y,
mu_x,
sigma_y,
sigma_x,
rho_y_x,
rho_x_x = NULL,
n,
randomized = TRUE
)Arguments
- a
Number of levels of the first factor (must be at least
2).- b
Number of levels of the second factor (default
1; use1if absent).- c
Number of levels of the third factor (default
1; use1if absent).- d
Number of levels of the fourth factor (default
1; use1if absent). Soa = 3, b = 2, c = 1, d = 1specifies a 3 \(\times\) 2 design.- n_covariates
Integer \(\ge 1\): the number of continuous covariates. Default
1.- mu_y
Numeric vector of length \(a \cdot b \cdot c \cdot d\) giving the population cell means of \(Y\), in the same row order as
expand.grid(A, B, C, D)(which varies factorAfastest, thenB, thenC, thenD).- mu_x
Numeric matrix of dimension \((a \cdot b \cdot c \cdot d) \times q\) giving the population cell means of each covariate (rows = cells in the same order as
mu_y; columns = covariates). Whenrandomized = TRUEevery column must be constant across cells.- sigma_y
Within-cell standard deviation of \(Y\) (a single positive number, common across cells).
- sigma_x
Within-cell standard deviations of the covariates. Either a single number (recycled to all
n_covariates) or a numeric vector of lengthn_covariates.- rho_y_x
Within-cell correlations between \(Y\) and each covariate. Either a single number (recycled to all
n_covariates) or a numeric vector of lengthn_covariates.- rho_x_x
Within-cell correlation matrix among the covariates, \(q \times q\). Default
NULL, interpreted as then_covariates-dimensional identity.- n
A single number (equal sample size per cell) or a numeric vector of length \(a \cdot b \cdot c \cdot d\) giving per-cell sample sizes (in the same row order as
mu_y).- randomized
Logical.
TRUE(the default) for a randomized design, each cell is sampled from the same population covariate distribution, somu_xmust be constant across cells.FALSEfor non-randomized / preexisting-groups designs in which the cells' population covariate means may differ.
Value
A long-format data.frame with one row per simulated
subject and the following columns:
A,B,C,DFactor columns for each present design factor (omitted when the factor is absent, i.e., its corresponding
a/b/c/dargument is1).x1,x2, ...,x<q>Numeric simulated covariates.
yNumeric simulated outcome.
Details
This is the factorial generalization of simulate_ancova_data
(which is the special case b = c = d = 1, n_covariates = 1). All
cells share the same within-cell covariance structure (homogeneity of
regression, the classical ANCOVA assumption); the difference between
randomized and non-randomized designs lies entirely in whether the cell
covariate means are constrained to be equal.
Why mu_x must be constant across cells when
randomized = TRUE. Random assignment forms each cell as an
exchangeable random sample from the same joint distribution of
covariates and outcome. Cell-specific covariate means would silently
break that interpretation. The function checks the constraint and
stops with an informative error if it is violated. (The same logic
that powers simulate_ancova_data.)
Cell ordering. The function uses
expand.grid's convention, factor A varies
fastest, then B, then C, then D. So for a
\(2 \times 3\) design, the six cells of mu_y are
\((A_1 B_1), (A_2 B_1), (A_1 B_2), (A_2 B_2), (A_1 B_3), (A_2 B_3)\).
If you build the cell specification by passing the factor levels to
expand.grid in the same order, the row indexing automatically
matches.
See also
simulate_ancova_data (one factor, one covariate
special case), simulate_anova_data,
simulate_regression_data
Other data simulators:
simulate_ancova_data(),
simulate_anova_data(),
simulate_longitudinal_gompertz(),
simulate_longitudinal_logistic(),
simulate_longitudinal_negative_exponential(),
simulate_longitudinal_polynomial(),
simulate_longitudinal_richards(),
simulate_regression_data()
Author
Ken Kelley kkelley@nd.edu
Examples
# 1. 2 x 2 randomized design, single covariate.
set.seed(113)
design_2x2 <- expand.grid(A = factor(1:2), B = factor(1:2))
design_2x2$mu_y <- c(50, 60, 55, 65) # cell means in expand.grid order
d1 <- simulate_ancova_factorial_data(
a = 2, b = 2,
mu_y = design_2x2$mu_y,
mu_x = matrix(10, nrow = 4, ncol = 1), # constant covariate mean
sigma_y = 8,
sigma_x = 3,
rho_y_x = 0.40,
n = 30
)
aggregate(y ~ A + B, data = d1, FUN = mean)
#> A B y
#> 1 1 1 48.65943
#> 2 2 1 60.48404
#> 3 1 2 58.24399
#> 4 2 2 65.81071
# 2. 3 x 2 nonrandomized design with two covariates and unequal n.
set.seed(113)
a <- 3; b <- 2; q <- 2
n_cells <- a * b
d2 <- simulate_ancova_factorial_data(
a = a, b = b,
n_covariates = q,
mu_y = c(50, 55, 60, 52, 58, 64),
mu_x = matrix(c(10, 11, 12, 9, 10, 11,
5, 6, 7, 4, 5, 6),
nrow = n_cells, ncol = q),
sigma_y = 8,
sigma_x = c(3, 2),
rho_y_x = c(0.40, 0.25),
rho_x_x = matrix(c(1, 0.3,
0.3, 1),
nrow = 2),
n = c(30, 25, 20, 35, 30, 25),
randomized = FALSE
)
head(d2)
#> A B x1 x2 y
#> 1 1 1 13.254525 8.5360960 50.29890
#> 2 1 1 11.325283 4.5916342 61.15584
#> 3 1 1 9.805804 6.4857128 56.11123
#> 4 1 1 8.257290 -0.4105572 39.99210
#> 5 1 1 10.668032 5.1076307 45.26514
#> 6 1 1 4.298724 3.7604657 36.75722
# 3. 2 x 2 x 2 randomized design with one covariate.
set.seed(113)
d3 <- simulate_ancova_factorial_data(
a = 2, b = 2, c = 2,
mu_y = c(50, 55, 52, 57, 53, 58, 55, 60), # 8 cells in A-fastest order
mu_x = matrix(10, nrow = 8, ncol = 1),
sigma_y = 8,
sigma_x = 3,
rho_y_x = 0.40,
n = 25
)
table(d3$A, d3$B, d3$C) # 25 per cell, 200 total
#> , , = 1
#>
#>
#> 1 2
#> 1 25 25
#> 2 25 25
#>
#> , , = 2
#>
#>
#> 1 2
#> 1 25 25
#> 2 25 25
#>