R implementation of the CAIDE estimator from:
Fava, B. (2024). Predicting the Distribution of Treatment Effects via Covariate-Adjustment, with an Application to Microcredit. arXiv:2407.14635.
CAIDE bounds the fraction of units with treatment effects below (or above) a given threshold in randomized experiments, using pre-treatment covariates and machine learning to sharpen classical Makarov (1982) bounds.
In a randomized experiment with outcome
which represents the fraction of units with an individual treatment effect at or below
Without further assumptions,
- Tighter bounds than standard Makarov bounds when covariates are predictive of outcomes
- Two estimation strategies: cross-fitting (recommended for most applications) and sample splitting
- Valid asymptotic inference with standard errors and confidence intervals using cross-fitting
- Finite-sample valid confidence intervals via the sample-splitting estimator
Install the required packages:
install.packages(c("tidyverse", "rsample", "ranger", "doMC", "foreach"))For additional ML models (optional):
install.packages(c("mlr3", "mlr3learners", "mlr3tuning",
"mlr3tuningspaces", "mlr3extralearners", "qrnn"))source("R/caide.R")
# Your data: Y (outcome), X (covariates), D (treatment), pX (propensity scores)
# For a completely randomized experiment: pX <- rep(mean(D), length(D))
result <- caide_cf(
Y = Y, X = X, D = D, pX = pX,
delta = 0,
K = 5,
models = "quant_rf",
quants_seq = seq(0, 1, length.out = 101),
mode = "cdf"
)
print_caide_results(result)| Function | Description |
|---|---|
caide_cf() |
Cross-fitting estimator (recommended). Uses K-fold cross-fitting for valid inference with efficient data use. |
caide_ss() |
Sample-splitting estimator. Finite-sample valid confidence intervals using DKW-type critical values. |
| Function | Description |
|---|---|
print_caide_results() |
Prints a formatted summary of bounds, standard errors, confidence intervals, and p-values. |
| Function | Description |
|---|---|
calc_cdf() |
Estimates conditional CDFs via ML (quantile RF, quantile NN, or mlr3 learners). |
calc_expectation() |
Estimates conditional expectations via ML (mlr3 learners). |
theta_t() |
Evaluates the Makarov-type statistic at a threshold. |
sigma2_hat_pX_known() |
Variance estimator (known propensity scores). |
sigma2_hat_pX_hat() |
Variance estimator (estimated/stratified propensity scores). |
makarov_cf() |
Computes Makarov bounds with cross-fitting inference. |
makarov_ss() |
Computes Makarov bounds with sample-splitting inference. |
sharp_makarov() |
Classical Makarov bounds without covariates. |
.calc_s_star() |
Finds optimal conditioning points for lower and upper bounds. |
.calc_s_star_oneside() |
Finds optimal conditioning point for one side only. |
result <- caide_cf(
Y, # Numeric vector of outcomes
X, # Data frame of covariates
D, # Binary treatment (0/1)
pX, # Propensity scores
delta = 0, # Treatment effect threshold
K = 5, # Cross-fitting folds
K_sub = 3, # Inner CV folds (model selection)
alpha = 0.05, # Significance level
models = "quant_rf", # ML model(s) to use
quants_seq = seq(0, 1, length.out = 101),
ncores = 1L, # Parallel cores
mode = "cdf", # "cdf" or "exp"
tune = FALSE # Hyperparameter tuning
)Arguments:
-
delta: Threshold for the treatment effect. Setdelta = 0to bound the fraction harmed. Setdelta = cfor any constantcto bound$P(Y(1) - Y(0) \le c)$ . -
models: One or more ML models. Options:-
"quant_rf"— Quantile random forest viaranger(recommended) -
"quant_nn"— Quantile neural network viaqrnn -
"none"— No covariate adjustment (classical Makarov bounds) - Any
mlr3regression learner:"regr.ranger","regr.xgboost","regr.svm","regr.nnet","regr.glmnet", etc.
When multiple models are provided, CAIDE automatically selects the best model per cross-fitting fold using an inner cross-validation loop.
-
-
mode:-
"cdf"— Uses estimated conditional CDFs to find optimal conditioning (sharper bounds, slower). Works with all model types. -
"exp"— Uses estimated conditional expectations as the conditioning variable (faster, requires mlr3 learners).
-
Output: A list containing:
-
makarov_lower,makarov_upper: Estimated bounds on$P(Y(1) - Y(0) \le \delta)$ -
sigma2_L,sigma2_U: Variance estimates -
vira: SJLS estimator results (for comparison)
Inference:
# 95% confidence interval for the lower bound
ci_low <- max(result$makarov_lower - qnorm(0.95) * sqrt(result$sigma2_L), 0)
ci_high <- result$makarov_lower + qnorm(0.95) * sqrt(result$sigma2_L)
# p-value for H0: theta(delta) >= 0 vs H1: theta(delta) > 0
pval <- 1 - pnorm(result$makarov_lower / sqrt(result$sigma2_L))result <- caide_ss(
Y, X, D, pX,
delta = 0,
K_sub = 2,
prop = 0.5, # Training proportion
alpha = 0.1, # Significance level
models = "quant_rf",
quants_seq = seq(0, 1, length.out = 101),
ncores = 1L,
tune = FALSE
)Inference (finite-sample valid):
# Confidence interval
ci_lower <- max(result$makarov_lower - result$c_alpha, 0)
ci_upper <- min(result$makarov_upper + result$c_alpha, 1)| Model ID | Package | Type | Description |
|---|---|---|---|
quant_rf |
ranger |
CDF | Quantile random forest (recommended) |
quant_nn |
qrnn |
CDF | Quantile neural network |
regr.ranger |
mlr3 |
CDF/Exp | Random forest regression |
regr.xgboost |
mlr3 |
CDF/Exp | Gradient boosted trees |
regr.svm |
mlr3 |
CDF/Exp | Support vector machine |
regr.nnet |
mlr3 |
CDF/Exp | Neural network |
regr.glmnet |
mlr3 |
CDF/Exp | Elastic net regression |
none |
— | — | No covariate adjustment |
See the examples/ directory:
example_application.R: Step-by-step walkthrough using simulated experimental dataexample_simulation.R: Monte Carlo study evaluating CAIDE performance
CAIDE/
├── R/
│ └── caide.R # All CAIDE functions
├── examples/
│ ├── example_application.R # Application walkthrough
│ └── example_simulation.R # Monte Carlo simulation
├── README.md
├── LICENSE
└── .gitignore
If you use this code, please cite:
@article{fava2024distribution,
title={The Distribution of Treatment Effects: Covariate-Adjusted Inference},
author={Fava, Bruno},
year={2024},
note={Working Paper}
}MIT License. See LICENSE for details.