Causal forests for heterogeneous effects (grf)
Follow the analysis.
Select a node to explore the method
Assemble X, W, Y
Data preparation — shapes the raw inputs into what the estimator expects.
Provide covariates, a treatment indicator, and an outcome (observational or experimental).
# Install: install.packages("grf")
library(grf)
n <- 2000; p <- 10
X <- matrix(rnorm(n * p), n, p)
W <- rbinom(n, 1, 0.5)
Y <- pmax(X[, 1], 0) * W + X[, 2] + rnorm(n)
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 a causal forest
The core estimate — where the causal quantity itself is computed.
causal_forest grows honest, heterogeneity-seeking trees and predicts each unit's conditional effect τ̂(x).
cf <- causal_forest(X, Y, W)
tau.hat <- predict(cf)$predictions
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.
Aggregate to the ATE
Uncertainty quantification — standard errors, intervals, and aggregation.
average_treatment_effect aggregates the forest to a doubly-robust ATE with a standard error.
average_treatment_effect(cf, target.sample = "all")
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
A covariate matrix X, a treatment vector W, and an outcome vector Y.
Show data format & exampleHide example
| Y | W | X1 | X2 |
|---|---|---|---|
| 1.2 | 1 | 0.4 | -0.7 |
| 0.3 | 0 | -1.1 | 0.2 |
| 2.1 | 1 | 0.9 | 1.3 |
| 0.1 | 0 | 0.0 | -0.4 |
Result figure rendered by StatsOtter from the package's documented example — unofficial community showcase; all credit to the original authors.
The estimate
\tau(x)=\mathbb E[\,Y(1)-Y(0)\mid X=x\,],\qquad \hat\tau(x)=\sum_i \alpha_i(x)\,\big(Y_i-\hat\mu(X_i)\big)
⚠️ Unofficial community showcase of grf (docs). Not affiliated with the authors — all credit to Susan Athey, Julie Tibshirani, Stefan Wager & Erik Sverdrup; this summarizes public documentation.
What it does. grf estimates heterogeneous treatment effects — how the effect τ(x) varies with covariates — using forests, with honest, asymptotically-normal confidence intervals. causal_forest() is the workhorse; average_treatment_effect() aggregates to the ATE.
How it works. It grows many honest trees that split to maximize heterogeneity in the treatment effect (a gradient-based generalization of random forests), then forms a weighted local moment estimator at each x. Out-of-bag predictions give each unit's τ(x); the forest also returns variance estimates for inference.
Assumptions. Unconfoundedness and overlap; honesty (separate splitting and estimation samples) underpins the valid intervals.
This forest-based causal-ML agenda was co-developed with Imbens's program on machine learning for causal inference.
What you get — A per-unit CATE estimate τ̂(x), plus the aggregated ATE with a standard error.
Example output
estimate std.err
0.4982731 0.0461145
Discuss the workflow (0)
Log in to join the discussion.