| Title: | Stratified Randomized Experiments |
|---|---|
| Description: | Estimate average treatment effects (ATEs) in stratified randomized experiments. 'sreg' supports a wide range of stratification designs, including matched pairs, n-tuple designs, and larger strata with many units — possibly of unequal size across strata. 'sreg' is designed to accommodate scenarios with multiple treatments and cluster-level treatment assignments, and accommodates optimal linear covariate adjustment based on baseline observable characteristics. 'sreg' computes estimators and standard errors based on Bugni, Canay, Shaikh (2018) <doi:10.1080/01621459.2017.1375934>; Bugni, Canay, Shaikh, Tabord-Meehan (2024+) <doi:10.48550/arXiv.2204.08356>; Jiang, Linton, Tang, Zhang (2023+) <doi:10.48550/arXiv.2201.13004>; Bai, Jiang, Romano, Shaikh, and Zhang (2024) <doi:10.1016/j.jeconom.2024.105740>; Bai (2022) <doi:10.1257/aer.20201856>; Bai, Romano, and Shaikh (2022) <doi:10.1080/01621459.2021.1883437>; Liu (2024+) <doi:10.48550/arXiv.2301.09016>; and Cytrynbaum (2024) <doi:10.3982/QE2475>. |
| Authors: | Juri Trifonov [aut, cre, cph], Yuehao Bai [aut], Azeem Shaikh [aut], Max Tabord-Meehan [aut] |
| Maintainer: | Juri Trifonov <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 2.1.0 |
| Built: | 2026-09-30 07:12:50 UTC |
| Source: | https://github.com/jutrifonov/sreg |
The data is taken from Chong et al. (2016), who study the effect of iron deficiency anemia (i.e., anemia caused by a lack of iron) on school-age children’s educational attainment and cognitive ability in Peru.
data("AEJapp")data("AEJapp")
A data frame with 215 observations on the 62 variables.
Chong, A., Cohen, I., Field, E., Nakasone, E., and Torero, M. (2016). Replication data for: Iron Deficiency and Schooling Attainment in Peru. Nashville, TN: American Economic Association [publisher], 2016. Ann Arbor, MI: Inter-university Consortium for Political and Social Research [distributor], 2019-10-12. doi:10.3886/E113624V1.
Chong, A., Cohen, I., Field, E., Nakasone, E., and Torero, M. (2016). Iron Deficiency and Schooling Attainment in Peru. American Economic Journal: Applied Economics, 8(4), 222–255. doi:10.1257/app.20140494.
data(AEJapp)data(AEJapp)
Visualize estimated ATEs and confidence intervals for objects of class sreg.
## S3 method for class 'sreg' plot( x, treatment_labels = NULL, title = "Estimated ATEs with Confidence Intervals", bar_fill = NULL, point_shape = 23, point_size = 3, point_fill = "white", point_stroke = 1.2, point_color = "black", label_color = "black", label_size = 4, bg_color = NULL, grid = TRUE, zero_line = TRUE, y_axis_title = NULL, x_axis_title = NULL, ... )## S3 method for class 'sreg' plot( x, treatment_labels = NULL, title = "Estimated ATEs with Confidence Intervals", bar_fill = NULL, point_shape = 23, point_size = 3, point_fill = "white", point_stroke = 1.2, point_color = "black", label_color = "black", label_size = 4, bg_color = NULL, grid = TRUE, zero_line = TRUE, y_axis_title = NULL, x_axis_title = NULL, ... )
x |
An object of class |
treatment_labels |
Optional vector of treatment labels to display on the y-axis. If |
title |
Optional plot title. Defaults to "Estimated ATEs with Confidence Intervals". |
bar_fill |
Optional fill color(s) for the confidence interval bars. Can be |
point_shape |
Optional shape of the point used to mark the estimated ATE. Default is 23 (a diamond). |
point_size |
Optional size of the point marking the ATE. |
point_fill |
Optional fill color of the ATE point shape. |
point_stroke |
Optional stroke (border) thickness of the ATE point shape. |
point_color |
Optional outline color of the ATE point. |
label_color |
Optional color of the text label displaying the estimate and standard error. |
label_size |
Optional size of the text label displaying the estimate and standard error. |
bg_color |
Optional background color of the plot panel. If |
grid |
Optional logical flag. If |
zero_line |
Optional logical flag. If |
y_axis_title |
Optional title of the y-axis. If |
x_axis_title |
Optional title of the x-axis. If |
... |
Additional arguments passed to other methods. |
Invisibly returns the ggplot object. Called for its side effects (i.e., generating a plot).
set.seed(22) data <- sreg.rgen( n = 120, tau.vec = c(0.2, 0.5), n.strata = 4, cluster = FALSE ) fit <- sreg(Y = data$Y, S = data$S, D = data$D) plot(fit) p <- plot( fit, treatment_labels = c("Program A", "Program B"), title = "Estimated treatment effects", x_axis_title = "ATE relative to control", bar_fill = c("#3B82F6", "#14B8A6") ) class(p)set.seed(22) data <- sreg.rgen( n = 120, tau.vec = c(0.2, 0.5), n.strata = 4, cluster = FALSE ) fit <- sreg(Y = data$Y, S = data$S, D = data$D) plot(fit) p <- plot( fit, treatment_labels = c("Program A", "Program B"), title = "Estimated treatment effects", x_axis_title = "ATE relative to control", bar_fill = c("#3B82F6", "#14B8A6") ) class(p)
sreg ObjectsPrint the summary table of estimation results for sreg objects.
## S3 method for class 'sreg' print(x, ...)## S3 method for class 'sreg' print(x, ...)
x |
An object of class |
... |
Additional arguments passed to other methods. |
No return value, called for side effects.
set.seed(21) data <- sreg.rgen( n = 80, tau.vec = c(0.2, 0.5), n.strata = 4, cluster = FALSE ) fit <- sreg( Y = data$Y, S = data$S, D = data$D, X = data[c("x_1", "x_2")] ) print(fit)set.seed(21) data <- sreg.rgen( n = 80, tau.vec = c(0.2, 0.5), n.strata = 4, cluster = FALSE ) fit <- sreg( Y = data$Y, S = data$S, D = data$D, X = data[c("x_1", "x_2")] ) print(fit)
Estimate the ATE(s) and the corresponding standard error(s) for a (collection of) treatment(s) relative to a control.
sreg( Y, S = NULL, D, G.id = NULL, Ng = NULL, X = NULL, HC1 = TRUE, small.strata = FALSE, k = NULL )sreg( Y, S = NULL, D, G.id = NULL, Ng = NULL, X = NULL, HC1 = TRUE, small.strata = FALSE, k = NULL )
Y |
a numeric |
S |
a numeric |
D |
a numeric |
G.id |
a numeric |
Ng |
a numeric |
X |
a |
HC1 |
a |
small.strata |
a |
k |
an optional positive integer specifying the number of units per small stratum, or the number of clusters per small stratum in cluster-randomized designs. When |
Supplying G.id selects cluster-level assignment; otherwise, treatment
is treated as assigned at the individual level. Setting
small.strata = FALSE selects the large-strata procedure. With
small.strata = TRUE, a common observed stratum size selects the
small-strata procedure, whereas varying stratum sizes select the mixed
procedure. The optional k validates the common size in a uniform
small-strata design and identifies the small-stratum size in a general
mixed design.
Under cluster-level assignment, adjustment is performed using cluster-level
covariates. Covariates supplied with one row per individual are replaced by
their within-cluster means. The package computes the mean outcome among the
available observations from each cluster and uses Ng as its represented
cluster size. If Ng = NULL, the represented cluster size is set equal
to the number of available observations in that cluster.
When covariates are supplied in a mixed design, they are used in both the
small- and large-strata components. If the large-strata component cannot
support the required treatment-by-stratum regressions, sreg() returns
an error suggesting fewer covariates or X = NULL.
An object of class sreg that is a list containing the following elements:
tau.hat: a numeric vector of ATE estimates, one for each active treatment arm relative to control
se.rob: a numeric vector of estimated standard errors
t.stat: a numeric vector of test statistics
p.value: a numeric vector of corresponding -values
CI.left, CI.right: numeric vectors containing the lower and upper endpoints of the 95% asymptotic confidence intervals
as.CI: the confidence-interval endpoints combined as c(CI.left, CI.right)
data: the data used for estimation, including the outcome, strata, treatment, and any supplied cluster or covariate variables
lin.adj: the covariates used for linear adjustment, or NULL when no adjustment is used
small.strata: a logical value recording the requested strata procedure
HC1: a logical value recording whether the HC1 finite-sample correction was applied
mixed.design: present and TRUE for mixed designs
res.small, res.big: for mixed designs, the fitted sreg objects for the small- and large-strata components
Depending on the selected design, the object may additionally contain the
estimated adjustment coefficients in ols.iter or beta.hat.
Authors:
Juri Trifonov [email protected]
Yuehao Bai [email protected]
Azeem Shaikh [email protected]
Max Tabord-Meehan [email protected]
Maintainer:
Juri Trifonov [email protected]
Bugni, F. A., Canay, I. A., and Shaikh, A. M. (2018). Inference Under Covariate-Adaptive Randomization. Journal of the American Statistical Association, 113(524), 1784–1796, doi:10.1080/01621459.2017.1375934.
Bugni, F., Canay, I., Shaikh, A., and Tabord-Meehan, M. (2024+). Inference for Cluster Randomized Experiments with Non-ignorable Cluster Sizes. Forthcoming in the Journal of Political Economy: Microeconomics, doi:10.48550/arXiv.2204.08356.
Jiang, L., Linton, O. B., Tang, H., and Zhang, Y. (2023+). Improving Estimation Efficiency via Regression-Adjustment in Covariate-Adaptive Randomizations with Imperfect Compliance. Forthcoming in Review of Economics and Statistics, doi:10.48550/arXiv.2201.13004.
Bai, Y., Jiang, L., Romano, J. P., Shaikh, A. M., and Zhang, Y. (2024). Covariate adjustment in experiments with matched pairs. Journal of Econometrics, 241(1), doi:10.1016/j.jeconom.2024.105740.
Bai, Y. (2022). Optimality of Matched-Pair Designs in Randomized Controlled Trials. American Economic Review, 112(12), doi:10.1257/aer.20201856.
Bai, Y., Romano, J. P., and Shaikh, A. M. (2022). Inference in Experiments With Matched Pairs. Journal of the American Statistical Association, 117(540), doi:10.1080/01621459.2021.1883437.
Liu, J. (2024). Inference for Two-stage Experiments under Covariate-Adaptive Randomization. doi:10.48550/arXiv.2301.09016.
Cytrynbaum, M. (2024). Covariate Adjustment in Stratified Experiments. Quantitative Economics, 15(4), 971–998, doi:10.3982/QE2475.
### Large strata with covariate adjustment set.seed(1) large_data <- sreg.rgen( n = 120, tau.vec = c(0.2, 0.5), n.strata = 4, cluster = FALSE ) fit_large <- sreg( Y = large_data$Y, S = large_data$S, D = large_data$D, X = large_data[c("x_1", "x_2")] ) fit_large$tau.hat fit_large$se.rob ### Uniform triplets: k is observed and may be omitted from sreg() set.seed(2) small_data <- sreg.rgen( n = 60, tau.vec = c(0.2, 0.5), cluster = FALSE, small.strata = TRUE, k = 3, treat.sizes = c(1, 1, 1) ) fit_small <- sreg( Y = small_data$Y, S = small_data$S, D = small_data$D, small.strata = TRUE ) fit_small$tau.hat ### Mixed design with general k-tuples: specify k in sreg() set.seed(3) mixed_data <- sreg.rgen( n = 60, tau.vec = 0.5, cluster = FALSE, mixed.strata = TRUE, n.small = 40, k = 4, treat.sizes = c(2, 2), n.strata = 2 ) fit_mixed <- suppressWarnings(sreg( Y = mixed_data$Y, S = mixed_data$S, D = mixed_data$D, small.strata = TRUE, k = 4 )) fit_mixed$mixed.design ### Cluster-randomized design set.seed(4) cluster_data <- sreg.rgen( n = 24, tau.vec = 0.5, n.strata = 3, cluster = TRUE ) fit_cluster <- sreg( Y = cluster_data$Y, S = cluster_data$S, D = cluster_data$D, G.id = cluster_data$G.id, Ng = cluster_data$Ng ) fit_cluster$tau.hat### Large strata with covariate adjustment set.seed(1) large_data <- sreg.rgen( n = 120, tau.vec = c(0.2, 0.5), n.strata = 4, cluster = FALSE ) fit_large <- sreg( Y = large_data$Y, S = large_data$S, D = large_data$D, X = large_data[c("x_1", "x_2")] ) fit_large$tau.hat fit_large$se.rob ### Uniform triplets: k is observed and may be omitted from sreg() set.seed(2) small_data <- sreg.rgen( n = 60, tau.vec = c(0.2, 0.5), cluster = FALSE, small.strata = TRUE, k = 3, treat.sizes = c(1, 1, 1) ) fit_small <- sreg( Y = small_data$Y, S = small_data$S, D = small_data$D, small.strata = TRUE ) fit_small$tau.hat ### Mixed design with general k-tuples: specify k in sreg() set.seed(3) mixed_data <- sreg.rgen( n = 60, tau.vec = 0.5, cluster = FALSE, mixed.strata = TRUE, n.small = 40, k = 4, treat.sizes = c(2, 2), n.strata = 2 ) fit_mixed <- suppressWarnings(sreg( Y = mixed_data$Y, S = mixed_data$S, D = mixed_data$D, small.strata = TRUE, k = 4 )) fit_mixed$mixed.design ### Cluster-randomized design set.seed(4) cluster_data <- sreg.rgen( n = 24, tau.vec = 0.5, n.strata = 3, cluster = TRUE ) fit_cluster <- sreg( Y = cluster_data$Y, S = cluster_data$S, D = cluster_data$D, G.id = cluster_data$G.id, Ng = cluster_data$Ng ) fit_cluster$tau.hat
The function generates the observed outcomes, treatment assignments, strata indicators, cluster indicators, cluster sizes, and covariates for estimating the treatment effect within the context of a stratified block randomization design under the covariate-adaptive randomization (CAR).
sreg.rgen( n, Nmax = 50, n.strata = 10, tau.vec = c(0), gamma.vec = c(0.4, 0.2, 1), cluster = TRUE, is.cov = TRUE, small.strata = FALSE, k = 3, treat.sizes = c(1, 1, 1), mixed.strata = FALSE, n.small = NULL, allocation.probs = NULL, stratum.effects = NULL, treatment.effects.by.stratum = NULL )sreg.rgen( n, Nmax = 50, n.strata = 10, tau.vec = c(0), gamma.vec = c(0.4, 0.2, 1), cluster = TRUE, is.cov = TRUE, small.strata = FALSE, k = 3, treat.sizes = c(1, 1, 1), mixed.strata = FALSE, n.small = NULL, allocation.probs = NULL, stratum.effects = NULL, treatment.effects.by.stratum = NULL )
n |
the total number of units when |
Nmax |
a maximum size of generated clusters (maximum number of observations in a cluster) |
n.strata |
an integer specifying the number of strata |
tau.vec |
a numeric |
gamma.vec |
a numeric |
cluster |
a |
is.cov |
a |
small.strata |
a |
k |
an integer specifying the number of units per stratum when |
treat.sizes |
a numeric |
mixed.strata |
a |
n.small |
the number of units (or clusters when |
allocation.probs |
an optional |
stratum.effects |
an optional numeric vector of length |
treatment.effects.by.stratum |
an optional |
A data.frame with one row per generated individual. Under individual-level assignment it contains n rows; under cluster-level assignment, n is the number of generated clusters and the number of rows equals the total number of individuals generated across those clusters. The returned columns are:
Y: the observed outcome
S: the stratum indicator
D: the treatment indicator indexed by , where denotes control
G.id: the cluster indicator, included when cluster = TRUE
Ng: the generated cluster size, included when cluster = TRUE
x_1, x_2: generated covariate columns, included when is.cov = TRUE
### Large-strata individual-level design set.seed(11) large_data <- sreg.rgen( n = 80, tau.vec = 0.5, n.strata = 4, cluster = FALSE ) ### Uniform matched pairs set.seed(12) pair_data <- sreg.rgen( n = 40, tau.vec = 0.5, cluster = FALSE, small.strata = TRUE, k = 2, treat.sizes = c(1, 1) ) ### Mixed design with 4-tuples and large strata set.seed(13) mixed_data <- sreg.rgen( n = 60, tau.vec = 0.5, cluster = FALSE, mixed.strata = TRUE, n.small = 40, k = 4, treat.sizes = c(2, 2), n.strata = 2 ) sort(table(mixed_data$S)) ### For cluster assignment, n counts clusters rather than observations set.seed(14) cluster_data <- sreg.rgen( n = 20, tau.vec = 0.5, n.strata = 2, cluster = TRUE ) length(unique(cluster_data$G.id))### Large-strata individual-level design set.seed(11) large_data <- sreg.rgen( n = 80, tau.vec = 0.5, n.strata = 4, cluster = FALSE ) ### Uniform matched pairs set.seed(12) pair_data <- sreg.rgen( n = 40, tau.vec = 0.5, cluster = FALSE, small.strata = TRUE, k = 2, treat.sizes = c(1, 1) ) ### Mixed design with 4-tuples and large strata set.seed(13) mixed_data <- sreg.rgen( n = 60, tau.vec = 0.5, cluster = FALSE, mixed.strata = TRUE, n.small = 40, k = 4, treat.sizes = c(2, 2), n.strata = 2 ) sort(table(mixed_data$S)) ### For cluster assignment, n counts clusters rather than observations set.seed(14) cluster_data <- sreg.rgen( n = 20, tau.vec = 0.5, n.strata = 2, cluster = TRUE ) length(unique(cluster_data$G.id))