Design-based estimators done fast (estimatr)
Follow the analysis.
Select a node to explore the method
Assemble the experiment
Data preparation — shapes the raw inputs into what the estimator expects.
Build a small completely-randomized experiment with one pre-treatment covariate.
# Install: install.packages("estimatr")
library(estimatr)
dat <- data.frame(Y = rnorm(100), Z = rbinom(100, 1, .5), X = rnorm(100))
Before using this step, make its assumptions and its output explicit. A useful peer note explains what you would check, what could go wrong, or what would change your interpretation.
Questions to explore- Which assumption matters most here, and what evidence could challenge it?
- What would you check before passing this output to the next step?
Choose a question to start your comment.
Peer discussion
- Bring your experience, a question, or a different perspective.
Log in to comment on this step.
Fit Lin's estimator
The core estimate — where the causal quantity itself is computed.
lm_lin centers covariates, adds the full treatment-by-covariate interactions, and uses HC2 standard errors.
lm_lin(Y ~ Z, covariates = ~ X, data = dat)
Before using this step, make its assumptions and its output explicit. A useful peer note explains what you would check, what could go wrong, or what would change your interpretation.
Questions to explore- Which assumption matters most here, and what evidence could challenge it?
- What would you check before passing this output to the next step?
Choose a question to start your comment.
Peer discussion
- Bring your experience, a question, or a different perspective.
Log in to comment on this step.
Inputs & data
Treatment Z, outcome Y and pre-treatment covariates X from a randomized experiment.
Show data format & exampleHide example
| Y | Z | X (age) |
|---|---|---|
| 5.2 | 1 | 34 |
| 4.1 | 0 | 51 |
| 6.0 | 1 | 29 |
| 3.8 | 0 | 60 |
Result figure rendered by StatsOtter from the package's documented example — unofficial community showcase; all credit to the original authors.
The estimate
Y_i=\alpha+\tau Z_i+\beta^\top\tilde X_i+\gamma^\top Z_i\tilde X_i+\varepsilon_i,\quad \tilde X_i=X_i-\bar X
⚠️ Unofficial community showcase of estimatr (docs). Not affiliated with the authors — all credit to the DeclareDesign team (Blair, Cooper, Coppock, Humphreys & Sonnet); this summarizes public documentation.
What it does. estimatr is the canonical software for the design-based estimators central to Peng Ding's work. lm_lin() implements Lin's (2013) covariate adjustment (treatment fully interacted with centered covariates); lm_robust() and difference_in_means() give the Neyman difference-in-means with conservative HC2 variance.
How it works. lm_lin() centers the covariates, adds all treatment×covariate interactions, and reads the ATE off the treatment coefficient with HC2 standard errors — the estimator Ding's textbook derives as never-harmful in large samples. Everything is implemented in C++ for speed.
Assumptions. Complete randomization (or a known design), SUTVA, fixed pre-treatment covariates; the HC2 variance is finite-sample conservative.
Implements methods Prof. Ding is known for; package authored by the DeclareDesign team.
What you get — The covariate-adjusted ATE (the Z coefficient) with an HC2 robust standard error and confidence interval.
Example output
Estimate Std. Error t value Pr(>|t|) CI Lower CI Upper DF
(Intercept) 0.0123 0.1402 0.088 0.930 -0.266 0.290 96
Z -0.0457 0.1989 -0.230 0.819 -0.440 0.349 96
X_c 0.0712 0.1421 0.501 0.617 -0.211 0.353 96
Z:X_c 0.0331 0.2011 0.165 0.870 -0.366 0.432 96
Discuss the workflow (0)
Log in to join the discussion.