Simulate Data From a One-Covariate ANCOVA Model
Source:R/simulate_ancova_data.R
simulate_ancova_data.RdGenerates random data appropriate for an analysis of covariance with one continuous outcome (\(Y\)) and one continuous covariate (\(X\)) crossed with \(a\) fixed groups. The covariate is treated as a random variable; \(Y\) and \(X\) are jointly multivariate normal within each group. Both the randomized-design case (population covariate mean common across groups) and the non-randomized / preexisting-groups case (population covariate means differ across groups; \(Y\)-on-\(X\) correlation may also differ) are supported. Per-group sample sizes may be equal or unequal.
Arguments
- mu_y
A numeric vector of length
agiving the population mean of \(Y\) in each group.- mu_x
When
randomized = TRUE, a single number giving the common population mean of \(X\) across all groups. Whenrandomized = FALSE, a numeric vector of lengthagiving the population covariate mean in each group.- sigma_y
The population standard deviation of \(Y\) (assumed common across groups).
- sigma_x
The population standard deviation of \(X\) (assumed common across groups).
- rho
The population correlation between \(Y\) and \(X\). When
randomized = TRUE, must be a single number (see Details). Whenrandomized = FALSE, may be a single number (recycled to allagroups) or a numeric vector of lengthagiving a distinct correlation in each group.- a
The number of fixed levels of the grouping factor (i.e., the number of conditions in a fixed-effects ANCOVA design). Use this argument when groups are the design levels of interest. (For sample-selected groups, e.g., classrooms or schools randomly drawn from a population, the convention in this package is to use
Jinstead.)- n
A single number (equal sample size per group) or a numeric vector of length
agiving the sample size in each group.- randomized
Logical.
TRUE(the default) for a randomized design (random assignment of subjects to groups, so that the population covariate mean is the same in every group).FALSEfor a non-randomized / preexisting-groups design.
Value
A long-format data.frame with one row per simulated subject
and three columns:
groupA factor with
alevels ("1", ...,as.character(a)) identifying each subject's group.yNumeric simulated outcome.
xNumeric simulated covariate.
This format is directly usable with aov(), lm(), and other
model-fitting functions.
Details
Each group's \((Y, X)\) pairs are drawn from a bivariate normal distribution with mean \((\mu_{Y,j}, \mu_{X,j})\) and covariance $$\Sigma_j = \begin{pmatrix} \sigma_Y^2 & \rho_j\,\sigma_Y\,\sigma_X \\ \rho_j\,\sigma_Y\,\sigma_X & \sigma_X^2 \end{pmatrix}.$$
Why rho must be a single number when randomized = TRUE.
Random assignment forms each group as an exchangeable random sample from
the same population. The bivariate distribution of \((Y, X)\) is
therefore the same in every group, including the correlation. Allowing
rho to differ across groups would silently break that
interpretation and produce data that no randomized design could plausibly
have generated. The function therefore stops with an error in that case;
use randomized = FALSE if you genuinely want group-specific
correlations.
Convention on group labels. The argument a is used here
(and throughout DMAR's experimental-design functions) for the number
of fixed levels of a designed factor, the levels you intend to
compare. The letter J is reserved for the number of sample-
selected groups, e.g., when classrooms or schools are randomly sampled
from a population (a random-effects context).
See also
mvrnorm, ci_c_ancova,
ss_aipe_c_ancova
Other data simulators:
simulate_ancova_factorial_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. Randomized design, two groups, equal n.
set.seed(113)
simple <- simulate_ancova_data(
mu_y = c(3, 5),
mu_x = 10,
sigma_y = 1,
sigma_x = 2,
rho = 0.8,
a = 2,
n = 20
)
head(simple)
#> group y x
#> 1 1 2.9708554 10.327468
#> 2 1 3.2960080 13.118574
#> 3 1 3.0362070 11.751984
#> 4 1 2.0565073 7.354049
#> 5 1 2.0626997 9.086845
#> 6 1 0.6000121 6.949545
# 2. Four preexisting groups with different correlations and unequal n.
# The first two groups share rho = 0.30; the second two share a larger
# rho = 0.60. The four groups are not used in the data-generation
# machinery beyond their per-group means and correlations -- they are
# just four distinct populations being sampled. In a downstream
# analysis these four groups could be cross-classified as a 2 x 2
# factorial design (e.g., the first factor distinguishing groups 1-2
# from groups 3-4, and the second factor distinguishing groups 1, 3
# from groups 2, 4) and analyzed via factorial ANCOVA.
set.seed(113)
preexisting <- simulate_ancova_data(
mu_y = c(50, 55, 60, 65),
mu_x = c(10, 12, 11, 13),
sigma_y = 8,
sigma_x = 3,
rho = c(0.30, 0.30, 0.60, 0.60),
a = 4,
n = c(40, 35, 45, 30),
randomized = FALSE
)
aggregate(cbind(y, x) ~ group, data = preexisting,
FUN = function(z) round(c(mean = mean(z), sd = sd(z)), 2))
#> group y.mean y.sd x.mean x.sd
#> 1 1 48.81 8.25 9.60 3.36
#> 2 2 56.16 7.65 13.30 2.55
#> 3 3 58.98 7.42 10.97 3.12
#> 4 4 65.39 7.44 13.37 3.36