swcrtcov source
codeStepped wedge cluster randomized experiments (SW-CREs) are a class of unidirectional crossover designs in which all clusters begin under the usual-care condition and the intervention is rolled out across the follow-up periods in a staggered fashion until every cluster is exposed. Although these designs have become popular in public health, medicine, and implementation science, clearly defined estimands and robust, estimand-aligned methods of analysis remain comparatively underdeveloped.
This tutorial illustrates the model-assisted analysis of covariance
(ANCOVA) framework of Chen and Li (2025) using the accompanying source
code swcrtcov.R. The framework (i) defines a class of
weighted average treatment effect (WATE) estimands that acknowledge the
multilevel data structure of a stepped wedge design, (ii) introduces
four ANCOVA working models that achieve covariate adjustment while
remaining consistent even under model misspecification, and (iii)
provides two complementary variance estimators—a design-based (DB)
plug-in estimator motivated by the staggered rollout randomization
scheme, and the cluster-robust standard error (CRSE). Throughout, we
generate a single stepped wedge data set, target the three interpretable
estimands, compare the five estimators, and then study their
finite-sample operating characteristics through a small simulation.
The source code depends only on base R:
## [1] "swcrt_ate" "swcrt_fit" "swcrt_plugin_cov" "swcrt_run_simulation"
## [5] "swcrt_simulate" "swcrt_treat" "swcrt_true_ate" "swcrt_vcovCR0"
The user-facing functions cover the entire workflow—data generation, estimation, variance, and Monte Carlo evaluation—as summarized below.
| Function | Purpose | Key arguments | Returns |
|---|---|---|---|
swcrt_treat() |
Monotone 0/1 treatment indicator across periods for a cluster that first adopts at a given time. | j (adoption time), J |
Length-J integer vector. |
swcrt_simulate() |
Simulate one individual-level balanced stepped wedge data set with informative cluster-period sizes, two structured covariates plus auxiliary noise covariates, known potential outcomes, and the three estimand weight columns. | I, J, rho0
(ICC), seed |
Analysis-period data frame (periods \(2,\ldots,J-1\)). |
swcrt_true_ate() |
Compute the true weighted ATE from the known potential outcomes (for simulation benchmarking). | data, weight,
y1, y0 |
Numeric scalar. |
swcrt_plugin_cov() |
Design-based (DB) plug-in covariance of the period-specific treatment effects under the staggered rollout scheme. | data, residual,
weights, I, J |
\((J-2)\times(J-2)\) covariance matrix. |
swcrt_vcovCR0() |
Cluster-robust (CR0) sandwich covariance for a weighted
lm; reproduces
clubSandwich::vcovCR(., "CR0"). |
fit (an lm),
cluster |
\(p\times p\) covariance matrix. |
swcrt_fit() |
Fit one estimator for one estimand by weighted least squares and return the point estimate with both standard errors. | data, outcome,
weight, method, covariates |
List: estimate, se_db,
se_crse, plus the fitted model. |
swcrt_ate() |
Convenience wrapper that runs all estimators across all estimands. | data, outcome,
weights, methods, covariates |
Tidy data frame, one row per (estimand, estimator). |
swcrt_run_simulation() |
Monte Carlo driver: repeatedly generates data, records the truth, and estimates every combination, summarizing bias, RMSE, average SEs, and CI coverage. | n_rep, gen_fun,
weights, methods, covariates,
seed |
List: estimates (raw draws) and
summary (metrics). |
The method argument of swcrt_fit() and
swcrt_ate() accepts "unadjusted",
"ANCOVA1", "ANCOVA2", "ANCOVA3",
and "ANCOVA4", corresponding to the five working models.
Helper functions prefixed with a dot
(e.g. .swcrt_formula(), .swcrt_design()) are
internal and are not intended to be called directly.
We adopt a finite population framework in which all potential outcomes are fixed quantities and the only source of variability is the randomization distribution. Consider a stepped wedge design with \(J\) periods indexed \(j = 1,\ldots,J\). The first period (all clusters under control) and the last period (all clusters under treatment) carry no treatment contrast and are excluded from the analysis owing to the absence of positivity; the analysis therefore proceeds over the \(J-2\) rollout periods \(2,\ldots,J-1\). For cluster \(i\), period \(j\), and individual \(k\), let \(Y_{ijk}(z)\) denote the potential outcome under treatment status \(z \in \{0,1\}\), with cluster-period size \(N_{ij}\).
The general class of weighted average treatment effect estimands during the rollout is \[ \tau \;=\; \frac{\sum_j \sum_i \sum_k w_{ijk}\{Y_{ijk}(1) - Y_{ijk}(0)\}} {\sum_j \sum_i \sum_k w_{ijk}}, \] where \(w_{ijk} \ge 0\) is an individual-specific weight. Different choices of weight yield different interpretable members of this family. We focus on the three estimands summarized below, which weigh the population of all individuals, all rollout periods, or all cluster-period cells, respectively.
| Estimand | Weight \(w_{ijk}\) | Weight column | Interpretation |
|---|---|---|---|
| \(\tau^{\text{ind}}\) (individual-average) | \(1\) | w1 |
Average of individual-level counterfactual contrasts over all individuals during the rollout; equal weight to each individual. |
| \(\tau^{\text{period}}\) (period-average) | \(N_j^{-1}\) | w2 |
Average of individual-level contrasts per period, further averaged over rollout periods; equal weight to each period. |
| \(\tau^{\text{cell}}\) (cell-average) | \(N_{ij}^{-1}\) | w3 |
Average of cluster-period cell-level mean contrasts over all cells during the rollout; equal weight to each cluster-period cell. |
When cluster-period sizes are heterogeneous, these estimands need not coincide, especially under informative cluster size—that is, when the cluster-period size \(N_{ij}\) is associated with the within-cluster counterfactual contrast. They coincide only when the sizes are homogeneous or the treatment effect is constant across cells. The choice among them should be guided by the study context and objectives.
To target the estimands above, we fit a working ANCOVA model by weighted least squares (WLS), using the weights \(w_{ijk}\) that correspond to the estimand of interest. Writing \(Z_{ij}\) for the treatment indicator and \(\widetilde{\mathbf{X}}_{ijk}\) for the period-mean-centered covariate vector, the four model formulations differ only in whether period-specific covariate main effects and treatment-by-covariate interactions are included:
| Estimator | Period-specific covariate effects | Treatment-by-covariate interactions |
|---|---|---|
| Unadjusted | — | — |
| ANCOVA I | \(\times\) | \(\times\) |
| ANCOVA II | \(\checkmark\) | \(\times\) |
| ANCOVA III | \(\times\) | \(\checkmark\) |
| ANCOVA IV | \(\checkmark\) | \(\checkmark\) |
Each estimator is model-assisted: the period-specific effect \(\widehat{\tau}_j\), and hence the overall estimator \(\widehat{\tau} = \sum_j w_j \widehat{\Delta}_j / \sum_j w_j\), remains consistent for the target estimand even when the working model is incorrectly specified. The unadjusted estimator is the special case of ANCOVA I with no covariate adjustment.
The variance of \(\widehat{\tau}\) is obtained from the covariance matrix of the period-specific effects, sandwiched by the (known) normalized weight vector \(\boldsymbol{\varpi}\). We consider two estimators of this covariance:
In swcrtcov.R, the DB covariance is computed by
swcrt_plugin_cov() and the CRSE (type CR0) by
swcrt_vcovCR0(); both are assembled, together with the
point estimate, inside swcrt_fit().
The function swcrt_simulate() generates one
individual-level data set from a balanced stepped wedge design. We set
the total number of periods to \(J =
7\), which corresponds to five rollout periods together with one
pre-rollout and one post-rollout period, and use \(I = 30\) clusters so that \(I/(J-1) = 5\) previously untreated clusters
adopt the intervention at each rollout time. The cluster-period sizes
increase with the period and are deliberately informative; the potential
outcomes are generated to be nonlinear in the covariates so as to probe
the model-robustness of the estimators.
## [1] 14041 21
head(dat[, c("cluster", "period", "schedule", "treatment",
"x1", "x2", "y_obs", "w1", "w2", "w3")], 5)| cluster | period | schedule | treatment | x1 | x2 | y_obs | w1 | w2 | w3 |
|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 7 | 0 | -0.5666667 | 0.1448924 | -2.3869946 | 1 | 0.0005777 | 0.0217391 |
| 1 | 2 | 7 | 0 | -0.5666667 | -0.4338905 | 0.1295666 | 1 | 0.0005777 | 0.0217391 |
| 1 | 2 | 7 | 0 | -0.5666667 | -0.6267966 | 1.5701729 | 1 | 0.0005777 | 0.0217391 |
| 1 | 2 | 7 | 0 | -0.5666667 | -0.1671781 | -0.8758256 | 1 | 0.0005777 | 0.0217391 |
| 1 | 2 | 7 | 0 | -0.5666667 | -1.3046724 | 6.0011129 | 1 | 0.0005777 | 0.0217391 |
The returned data frame is already restricted to the rollout periods
\(2,\ldots,6\) and contains the period
indicator columns period_2,…,period_6, the
adoption time schedule, the treatment indicator
treatment, the centered covariates, the observed outcome
y_obs, the (unobservable) potential outcomes
y0 and y1, and the three weight columns. The
staggered rollout is most transparent in the cluster-by-period treatment
matrix, in which clusters are ordered by their adoption time:
cp <- unique(dat[, c("cluster", "schedule", "period", "treatment")])
wide <- reshape(cp[, c("cluster", "schedule", "period", "treatment")],
idvar = c("cluster", "schedule"), timevar = "period",
direction = "wide")
wide <- wide[order(wide$schedule, wide$cluster), ]
colnames(wide) <- sub("treatment.", "period_", colnames(wide), fixed = TRUE)
knitr::kable(head(wide, 12), row.names = FALSE,
caption = "Treatment status by cluster and rollout period (1 = treated).")| cluster | schedule | period_2 | period_3 | period_4 | period_5 | period_6 |
|---|---|---|---|---|---|---|
| 5 | 2 | 1 | 1 | 1 | 1 | 1 |
| 9 | 2 | 1 | 1 | 1 | 1 | 1 |
| 10 | 2 | 1 | 1 | 1 | 1 | 1 |
| 19 | 2 | 1 | 1 | 1 | 1 | 1 |
| 23 | 2 | 1 | 1 | 1 | 1 | 1 |
| 14 | 3 | 0 | 1 | 1 | 1 | 1 |
| 15 | 3 | 0 | 1 | 1 | 1 | 1 |
| 20 | 3 | 0 | 1 | 1 | 1 | 1 |
| 22 | 3 | 0 | 1 | 1 | 1 | 1 |
| 24 | 3 | 0 | 1 | 1 | 1 | 1 |
| 6 | 4 | 0 | 0 | 1 | 1 | 1 |
| 12 | 4 | 0 | 0 | 1 | 1 | 1 |
Because the potential outcomes are known in this simulated trial, we
can compute the true value of each estimand directly from the
individual-level counterfactual contrasts using
swcrt_true_ate(). The three estimands differ in value, a
direct consequence of the informative cluster-period size built into the
data-generating process.
true_vals <- c(
ind = swcrt_true_ate(dat, "w1"),
period = swcrt_true_ate(dat, "w2"),
cell = swcrt_true_ate(dat, "w3")
)
round(true_vals, 3)## ind period cell
## 0.684 0.588 0.492
A single call to swcrt_ate() fits all five estimators
for each of the three estimands and returns the point estimate together
with the design-based and cluster-robust standard errors. Following the
primary analysis in Chen and Li (2025), we adjust for the two baseline
covariates \(\mathbf{X}_{ijk} = (X_{ij1},
X_{ijk2})\), supplied here as x1 and
x2.
fit_tab <- swcrt_ate(dat, outcome = "y_obs",
weights = c(ind = "w1", period = "w2", cell = "w3"),
covariates = c("x1", "x2"))
fit_tab[, c("estimate", "se_db", "se_crse")] <-
round(fit_tab[, c("estimate", "se_db", "se_crse")], 3)
knitr::kable(fit_tab,
col.names = c("Estimand", "Estimator", "Estimate", "SE (DB)", "SE (CRSE)"),
caption = "Point estimates and standard errors for one simulated trial.")| Estimand | Estimator | Estimate | SE (DB) | SE (CRSE) |
|---|---|---|---|---|
| ind | unadjusted | 0.751 | 0.167 | 0.150 |
| ind | ANCOVA1 | 0.650 | 0.142 | 0.126 |
| ind | ANCOVA2 | 0.640 | 0.137 | 0.121 |
| ind | ANCOVA3 | 0.670 | 0.127 | 0.115 |
| ind | ANCOVA4 | 0.676 | 0.099 | 0.088 |
| period | unadjusted | 0.633 | 0.165 | 0.148 |
| period | ANCOVA1 | 0.540 | 0.149 | 0.134 |
| period | ANCOVA2 | 0.529 | 0.141 | 0.127 |
| period | ANCOVA3 | 0.553 | 0.131 | 0.120 |
| period | ANCOVA4 | 0.557 | 0.104 | 0.091 |
| cell | unadjusted | 0.505 | 0.164 | 0.146 |
| cell | ANCOVA1 | 0.431 | 0.146 | 0.132 |
| cell | ANCOVA2 | 0.420 | 0.144 | 0.132 |
| cell | ANCOVA3 | 0.446 | 0.128 | 0.116 |
| cell | ANCOVA4 | 0.475 | 0.108 | 0.100 |
Two patterns, both anticipated by the theory, are already visible. First, within each estimand the covariate-adjusted estimators return standard errors that are smaller than those of the unadjusted estimator, illustrating the efficiency gain from covariate adjustment. Second, the design-based standard errors are systematically at least as large as the cluster-robust ones, consistent with the conservativeness of the DB estimator.
A 95% Wald confidence interval for any row is formed in the usual way. For the individual-average treatment effect estimated by ANCOVA III, using the design-based standard error:
row <- subset(swcrt_ate(dat, weights = c(ind = "w1"),
methods = "ANCOVA3", covariates = c("x1", "x2")))
ci <- c(lower = row$estimate - 1.96 * row$se_db,
est = row$estimate,
upper = row$estimate + 1.96 * row$se_db)
round(ci, 3)## lower est upper
## 0.421 0.670 0.919
The framework places no restriction on the covariate set. As discussed in Chen and Li (2025), the cluster-period size \(N_{ij}\) may itself be adjusted for as an additional covariate; here we illustrate by appending the three auxiliary covariates available in the generated data.
swcrt_ate(dat, weights = c(ind = "w1"),
methods = c("unadjusted", "ANCOVA1", "ANCOVA3"),
covariates = c("x1", "x2", "x3", "x4", "x5"))| estimand | method | estimate | se_db | se_crse |
|---|---|---|---|---|
| ind | unadjusted | 0.7511653 | 0.1673459 | 0.1496787 |
| ind | ANCOVA1 | 0.6450304 | 0.1391762 | 0.1238342 |
| ind | ANCOVA3 | 0.6338824 | 0.1221130 | 0.1116755 |
A single trial cannot speak to bias or coverage. We therefore
evaluate the estimators over repeated stepped wedge experiments using
swcrt_run_simulation(), which for each replication
generates a new data set, records the true estimand from the potential
outcomes, and estimates every method-by-estimand combination. We
summarize performance through the relative bias (BIAS), the root mean
square error (RMSE), the empirical standard error (ESE), the average
standard errors (ASE) from the DB and CRSE approaches, and the empirical
coverage of 95% confidence intervals.
To keep the runtime modest we use 100 replications at two cluster sizes, \(I \in \{30, 60\}\); the original study used 1{,}000 replications and \(I \in \{18, 30, 60, 120\}\). The qualitative conclusions are unchanged.
run_one <- function(I, n_rep = 100) {
sim <- swcrt_run_simulation(
n_rep = n_rep,
gen_fun = function() swcrt_simulate(I, 7, rho0 = 0.1),
weights = c(ind = "w1", period = "w2", cell = "w3"),
covariates = c("x1", "x2"),
seed = 2024, progress = FALSE)
cbind(I = I, sim$summary)
}
sim30 <- run_one(30)
sim60 <- run_one(60)
sim_all <- rbind(sim30, sim60)The helper below renders the results in the layout of the simulation tables in Chen and Li (2025).
pretty_table <- function(df, estimand_label, estimand_name) {
d <- df[df$estimand == estimand_label, ]
meth_map <- c(unadjusted = "UN", ANCOVA1 = "AN I", ANCOVA2 = "AN II",
ANCOVA3 = "AN III", ANCOVA4 = "AN IV")
out <- data.frame(
I = d$I,
Estimator = meth_map[d$method],
BIAS = round(d$rel_bias, 3),
RMSE = round(d$rmse, 3),
ESE = round(d$emp_sd, 3),
`ASE.DB` = round(d$mean_se_db, 3),
`ASE.CRSE`= round(d$mean_se_crse, 3),
`Cov.DB` = round(d$cover_db, 3),
`Cov.CRSE`= round(d$cover_crse, 3),
check.names = FALSE, row.names = NULL)
out$I[duplicated(out$I)] <- ""
knitr::kable(out, row.names = FALSE, caption = paste0(
"Results for the ", estimand_name, " ($\\", "tau^{", estimand_label,
"}$). BIAS = relative bias; RMSE = root mean squared error; ",
"ESE = empirical standard error; ASE = average standard error ",
"(DB = design-based plug-in, CRSE = cluster-robust); ",
"Coverage = empirical coverage of 95% CIs over 200 replications."))
}| I | Estimator | BIAS | RMSE | ESE | ASE.DB | ASE.CRSE | Cov.DB | Cov.CRSE |
|---|---|---|---|---|---|---|---|---|
| 30 | UN | 0.010 | 0.142 | 0.152 | 0.163 | 0.146 | 0.97 | 0.94 |
| AN I | 0.009 | 0.083 | 0.102 | 0.130 | 0.117 | 0.99 | 0.99 | |
| AN II | 0.011 | 0.096 | 0.110 | 0.130 | 0.117 | 0.98 | 0.97 | |
| AN III | 0.007 | 0.081 | 0.099 | 0.109 | 0.098 | 0.98 | 0.98 | |
| AN IV | 0.002 | 0.086 | 0.103 | 0.097 | 0.085 | 0.97 | 0.94 | |
| 60 | UN | 0.009 | 0.091 | 0.113 | 0.112 | 0.106 | 0.98 | 0.97 |
| AN I | 0.013 | 0.060 | 0.091 | 0.088 | 0.084 | 1.00 | 0.99 | |
| AN II | 0.017 | 0.064 | 0.095 | 0.090 | 0.085 | 1.00 | 1.00 | |
| AN III | 0.008 | 0.059 | 0.092 | 0.074 | 0.071 | 0.98 | 0.98 | |
| AN IV | 0.006 | 0.061 | 0.095 | 0.071 | 0.067 | 0.98 | 0.97 |
| I | Estimator | BIAS | RMSE | ESE | ASE.DB | ASE.CRSE | Cov.DB | Cov.CRSE |
|---|---|---|---|---|---|---|---|---|
| 30 | UN | 0.005 | 0.132 | 0.145 | 0.159 | 0.142 | 0.97 | 0.94 |
| AN I | 0.002 | 0.082 | 0.104 | 0.128 | 0.115 | 0.99 | 0.99 | |
| AN II | 0.005 | 0.094 | 0.112 | 0.127 | 0.115 | 0.98 | 0.98 | |
| AN III | 0.000 | 0.078 | 0.100 | 0.106 | 0.095 | 1.00 | 0.97 | |
| AN IV | -0.015 | 0.084 | 0.103 | 0.095 | 0.083 | 0.96 | 0.93 | |
| 60 | UN | -0.001 | 0.088 | 0.109 | 0.108 | 0.103 | 0.99 | 0.98 |
| AN I | 0.006 | 0.055 | 0.086 | 0.087 | 0.082 | 1.00 | 1.00 | |
| AN II | 0.011 | 0.059 | 0.089 | 0.089 | 0.084 | 1.00 | 1.00 | |
| AN III | -0.001 | 0.056 | 0.087 | 0.072 | 0.069 | 0.99 | 0.99 | |
| AN IV | -0.009 | 0.059 | 0.091 | 0.069 | 0.065 | 0.99 | 0.97 |
| I | Estimator | BIAS | RMSE | ESE | ASE.DB | ASE.CRSE | Cov.DB | Cov.CRSE |
|---|---|---|---|---|---|---|---|---|
| 30 | UN | 0.014 | 0.132 | 0.149 | 0.160 | 0.143 | 0.96 | 0.95 |
| AN I | 0.015 | 0.086 | 0.110 | 0.129 | 0.116 | 1.00 | 0.99 | |
| AN II | 0.022 | 0.097 | 0.118 | 0.129 | 0.117 | 0.98 | 0.97 | |
| AN III | 0.016 | 0.080 | 0.105 | 0.108 | 0.097 | 0.99 | 0.98 | |
| AN IV | 0.026 | 0.086 | 0.107 | 0.097 | 0.085 | 0.96 | 0.92 | |
| 60 | UN | 0.008 | 0.085 | 0.107 | 0.108 | 0.102 | 1.00 | 0.97 |
| AN I | 0.013 | 0.057 | 0.088 | 0.087 | 0.083 | 0.99 | 0.99 | |
| AN II | 0.022 | 0.060 | 0.091 | 0.089 | 0.084 | 0.99 | 0.99 | |
| AN III | 0.008 | 0.056 | 0.088 | 0.073 | 0.069 | 0.99 | 0.99 | |
| AN IV | 0.013 | 0.058 | 0.091 | 0.070 | 0.066 | 0.99 | 0.97 |
The simulation reproduces the central messages of Chen and Li (2025). For every estimand, the relative bias and RMSE decrease as the number of clusters \(I\) grows, corroborating the consistency of all five estimators. The covariate-adjusted estimators attain smaller RMSE than the unadjusted estimator, confirming that adjusting for baseline covariates improves efficiency, although the most efficient working model depends on the data-generating process.
The two variance estimators exhibit complementary finite-sample behavior. For the unadjusted, ANCOVA I, and ANCOVA II estimators, the design-based approach tends to be conservative when the number of clusters is small, whereas the cluster-robust approach yields average standard errors closer to the empirical standard error. For ANCOVA III, which includes treatment-by-covariate interactions but no period-specific covariate main effects, the design-based approach yields average standard errors close to the empirical standard error with near-nominal coverage across cluster sizes. For ANCOVA IV, which additionally includes period-specific interactions and therefore estimates the largest number of parameters, the design-based variance can be slightly underestimated when \(I\) is small but improves as \(I\) increases.
These observations lead to a consistent practical recommendation. When a sufficient number of clusters are available, ANCOVA estimators with treatment-by-covariate interactions (ANCOVA III or IV) are preferred for their efficiency. When only a limited number of clusters are present, the ANCOVA III estimator—with treatment-by-covariate interactions but without period-specific covariate main effects—offers the best balance of efficiency and finite-sample stability, and the design-based standard error is the more reliable choice for ANCOVA III and IV, whereas the cluster-robust standard error is preferable for the unadjusted, ANCOVA I, and ANCOVA II estimators.
## R version 4.6.0 (2026-04-24)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.4 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so; LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8 LC_COLLATE=C.UTF-8
## [5] LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8 LC_PAPER=C.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C
##
## time zone: UTC
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## loaded via a namespace (and not attached):
## [1] digest_0.6.39 R6_2.6.1 codetools_0.2-20 fastmap_1.2.0 xfun_0.59
## [6] cachem_1.1.0 knitr_1.51 htmltools_0.5.9 rmarkdown_2.31 lifecycle_1.0.5
## [11] cli_3.6.6 sass_0.4.10 jquerylib_0.1.4 compiler_4.6.0 tools_4.6.0
## [16] evaluate_1.0.5 bslib_0.11.0 yaml_2.3.12 rlang_1.2.0 jsonlite_2.0.0
Chen, X. and Li, F. (2025). Model-assisted analysis of covariance estimators for stepped wedge cluster randomized experiments. Scandinavian Journal of Statistics.