Skip to contents

Implements the IRM variant of Chernozhukov et al. (2018) double machine learning, which allows treatment-effect heterogeneity by fitting separate outcome regressions for \(T=0\) and \(T=1\) alongside a propensity model. Uses DoubleML::DoubleMLIRM when available; otherwise falls back to a hand-rolled cross-fit estimator using logistic regression for the propensity score and ridge regression for the conditional outcome regressions.

Thin R wrapper that dispatches to the CRAN DoubleML package's DoubleML::DoubleMLIRM R6Class, mirroring the Python sibling morie.estimate_irm() (which dispatches to the Python DoubleML package).

Usage

morie_estimate_irm(
  data,
  treatment,
  outcome,
  covariates,
  n_folds = 5,
  random_state = 42
)

morie_estimate_irm(
  data,
  treatment,
  outcome,
  covariates,
  n_folds = 5,
  random_state = 42
)

Arguments

data

A data.frame containing outcome, treatment, and covariates.

treatment

Column name of the binary treatment.

outcome

Column name of the outcome.

covariates

Character vector of covariate column names.

n_folds

Number of cross-fitting folds (default 5).

random_state

Random seed (default 42).

Value

Named list with ate, se, ci_lower, ci_upper, n, method.

A list with components: ate, se, ci_lower, ci_upper, n, method ("IRM (DoubleML)").

Details

Following the DoubleML R package's own conventions, this uses the mlr3 ecosystem for the nuisance learners (ml_g for \(E[Y|T,X]\) and ml_m for \(P(T=1|X)\)). Defaults are lrn("regr.lm") and lrn("classif.log_reg"), which require nothing beyond stats. For higher-capacity defaults, install ranger and pass lrn("regr.ranger") / lrn("classif.ranger") via the underlying DoubleML::DoubleMLIRM$new() directly.

Following Chernozhukov et al. (2018), the IRM extends the partially linear model by allowing fully heterogeneous treatment effects: $$Y = g_0(T, X) + U,\quad E[U|T,X] = 0$$ $$T = m_0(X) + V,\quad E[V|X] = 0$$

CRAN Suggests

Requires the suggested packages DoubleML, mlr3, and mlr3learners. Install with install.packages(c("DoubleML", "mlr3", "mlr3learners")). If any are unavailable, the function raises an informative error.

References

Chernozhukov, V., Chetverikov, D., Demirer, M., Duflo, E., Hansen, C., Newey, W., & Robins, J. (2018). Double/debiased machine learning for treatment and structural parameters. The Econometrics Journal, 21(1), C1–C68.

Chernozhukov, V., Chetverikov, D., Demirer, M., Duflo, E., Hansen, C., Newey, W., & Robins, J. (2018). Double/debiased machine learning for treatment and structural parameters. The Econometrics Journal, 21(1), C1–C68. doi:10.1111/ectj.12097

Bach, P., Chernozhukov, V., Kurz, M. S., & Spindler, M. (2024). DoubleML – An object-oriented implementation of double machine learning in R. Journal of Statistical Software, 108(3). doi:10.18637/jss.v108.i03

Examples

set.seed(1)
n <- 200
X <- matrix(rnorm(n * 3), n, 3)
d <- rbinom(n, 1, plogis(X[, 1]))
y <- 0.5 * d + X[, 1] + rnorm(n)
df <- data.frame(y = y, d = d, x1 = X[, 1], x2 = X[, 2], x3 = X[, 3])
morie_estimate_irm(df, treatment = "d", outcome = "y",
                   covariates = c("x1", "x2", "x3"))
#> $ate
#> [1] 0.6077994
#> 
#> $se
#> [1] 0.2202892
#> 
#> $ci_lower
#> [1] 0.1760405
#> 
#> $ci_upper
#> [1] 1.039558
#> 
#> $n
#> [1] 200
#> 
#> $method
#> [1] "IRM (DoubleML)"
#> 
# \donttest{
if (requireNamespace("DoubleML", quietly = TRUE) &&
  requireNamespace("mlr3", quietly = TRUE) &&
  requireNamespace("mlr3learners", quietly = TRUE)) {
  set.seed(1)
  n <- 200
  X <- matrix(rnorm(n * 5), n, 5)
  ps <- plogis(X[, 1] - X[, 2])
  T <- rbinom(n, 1, ps)
  Y <- 0.5 * T + X[, 1] + rnorm(n)
  df <- data.frame(Y = Y, T = T, X)
  morie_estimate_irm(df,
    treatment = "T", outcome = "Y",
    covariates = paste0("X", 1:5)
  )
}
#> $ate
#> [1] -0.03830964
#> 
#> $se
#> [1] 0.2226361
#> 
#> $ci_lower
#> [1] -0.4746684
#> 
#> $ci_upper
#> [1] 0.3980491
#> 
#> $n
#> [1] 200
#> 
#> $method
#> [1] "IRM (DoubleML)"
#> 
# }