AIPW

R Package: Augmented Inverse Probability Weighted (AIPW) Estimation for Average Causal Effect

https://github.com/yqzhong7/aipw

Science Score: 36.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
    Found 3 DOI reference(s) in README
  • Academic publication links
  • Committers with academic emails
    1 of 3 committers (33.3%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (18.0%) to scientific vocabulary

Keywords

causal-inference machine-learning r robust-estimators
Last synced: 10 months ago · JSON representation

Repository

R Package: Augmented Inverse Probability Weighted (AIPW) Estimation for Average Causal Effect

Basic Info
Statistics
  • Stars: 24
  • Watchers: 1
  • Forks: 7
  • Open Issues: 0
  • Releases: 1
Topics
causal-inference machine-learning r robust-estimators
Created over 6 years ago · Last pushed over 1 year ago
Metadata Files
Readme License

README.Rmd

---
title: "AIPW: Augmented Inverse Probability Weighting"
output:
  github_document
---

[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
[![Codecov test coverage](https://codecov.io/gh/yqzhong7/AIPW/branch/master/graph/badge.svg)](https://app.codecov.io/gh/yqzhong7/AIPW?branch=master)
[![R build status](https://github.com/yqzhong7/AIPW/workflows/R-CMD-check/badge.svg)](https://github.com/yqzhong7/AIPW/actions)
[![](https://www.r-pkg.org/badges/version/AIPW?color=blue)](https://cran.r-project.org/package=AIPW)





__Contributors:__ [Yongqi Zhong](https://github.com/yqzhong7), [Ashley Naimi](https://github.com/ainaimi), [Gabriel Conzuelo](https://github.com/gconzuelo), [Edward Kennedy](https://github.com/ehkennedy)


```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  fig.width = 6,
  fig.height = 4,
  fig.path = "man/figures/",
  comment = "#>"
)
```

----------------

Augmented inverse probability weighting (AIPW) is a doubly robust estimator for causal inference. The `AIPW` package is designed for estimating the average treatment effect of a binary exposure on risk difference (RD), risk ratio (RR) and odds ratio (OR) scales with user-defined stacked machine learning algorithms ([SuperLearner](https://CRAN.R-project.org/package=SuperLearner) or [sl3](https://tlverse.org/sl3/index.html)). Users need to examine causal assumptions (e.g., consistency) before using this package. 

If you find this package is helpful, please consider to cite:
```
@article{zhong_aipw_2021,
    author = {Zhong, Yongqi and Kennedy, Edward H and Bodnar, Lisa M and Naimi, Ashley I},
    title = {AIPW: An R Package for Augmented Inverse Probability Weighted Estimation of Average Causal Effects},
    journal = {American Journal of Epidemiology},
    year = {2021},
    month = {07},
    issn = {0002-9262},
    doi = {10.1093/aje/kwab207},
    url = {https://doi.org/10.1093/aje/kwab207},
}
```

---------------

## Contents:

  * ##### [Updates](#Updates)
  * ##### [Installation](#Installation)
  * ##### [Example](#Example)
    + ###### [Setup example data](#data)
    + ###### [One line version](#one_line)
  * ##### [Repeated Fitting](#rep)
  * ##### [Parallelization and progress bar](#par) 
  * ##### [Use tmle/tmle3 as input](#tmle)
  * ##### [References](#ref)

---------

## Updates

### 2025-04-05 Updates

#### Repeated Cross-fitting
The major new feature introduced is the `Repeated` class, which allows for repeated cross-fitting procedures to mitigate randomness due to data splits in machine learning-based estimation as suggested by Chernozhukov et al. (2018). This feature:
- Enables running the cross-fitting procedure multiple times to produce more stable estimates
- Provides methods to summarize results using median-based approaches
- Supports parallelization with `future.apply`
- Includes visualization of estimate distributions across repetitions
- See the [Repeated Cross-fitting vignette](vignettes/Repated_Crossfitting.Rmd) for more details

#### Continuous Outcome Support Improvements
- Fixed handling of continuous outcomes for exposure models (#50)
- Improved handling of non-binary treatments
- Fixed Q.model for continuous outcomes

#### Infrastructure Improvements
- Updated GitHub Actions workflows for R-CMD-check, test coverage, and pkgdown
- Removed Travis CI in favor of GitHub Actions
- Enhanced test coverage with additional tests for the new Repeated class
- Updated documentation and namespace for new functionality

#### Support Changes
- New GitHub versions (after v0.6.3.1) no longer support sl3 and tmle3
- Users requiring sl3 and tmle3 support should install via `remotes::install_github("yqzhong7/AIPW@aje_version")`

#### Bug Fixes
- Fixed repeated fitting when stratified_fit is enabled
- Fixed handling of Q.model
- Added proper error handling for various edge cases
- Fixed continuous outcome for exposure model
- Improved cross-fitting to reduce randomness (#38)

---------

## Installation

### CRAN version
```{r installation cran, eval=FALSE}
install.packages("AIPW")
```

### Github version
```{r installation, eval=FALSE}
install.packages("remotes")
remotes::install_github("yqzhong7/AIPW")
```

__* CRAN version only supports SuperLearner and tmle. New GitHub versions (after v0.6.3.1) no longer support sl3 and tmle3. If you are still interested in using the version with sl3 and tmle3 support, please install `remotes::install_github("yqzhong7/AIPW@aje_version")` Please install the Github version (master branch) if you choose to use sl3 and tmle3.__

## Example

### Setup example data
```{r example data}
set.seed(888)
data("eager_sim_obs")
outcome <- eager_sim_obs$sim_Y
exposure <- eager_sim_obs$sim_A
#covariates for both outcome model (Q) and exposure model (g)
covariates <- as.matrix(eager_sim_obs[-1:-2])

# covariates <- c(rbinom(N,1,0.4)) #a vector of a single covariate is also supported
```

### One line version (`AIPW` class: method chaining from R6class)

```{r one_line, fig.width=8}
library(AIPW)
library(SuperLearner)
library(ggplot2)
AIPW_SL <- AIPW$new(Y = outcome,
                    A = exposure,
                    W = covariates, 
                    Q.SL.library = c("SL.mean","SL.glm"),
                    g.SL.library = c("SL.mean","SL.glm"),
                    k_split = 3,
                    verbose=FALSE)$
  fit()$
  #Default truncation
  summary(g.bound = 0.025)$ 
  plot.p_score()$
  plot.ip_weights()
```

To see the results, set `verbose = TRUE`(default) or:
```{r res}
print(AIPW_SL$result, digits = 2)
```

To obtain average treatment effect among the treated/controls (ATT/ATC), `statified_fit()` must be used:
```{r}
AIPW_SL_att <- AIPW$new(Y = outcome,
                    A = exposure,
                    W = covariates, 
                    Q.SL.library = c("SL.mean","SL.glm"),
                    g.SL.library = c("SL.mean","SL.glm"),
                    k_split = 3,
                    verbose=T)
suppressWarnings({
  AIPW_SL_att$stratified_fit()$summary()
})
```


You can also use the `aipw_wrapper()` to wrap `new()`, `fit()` and `summary()` together (also support method chaining):
```{r wrapper, eval=F}
AIPW_SL <- aipw_wrapper(Y = outcome,
                        A = exposure,
                        W = covariates, 
                        Q.SL.library = c("SL.mean","SL.glm"),
                        g.SL.library = c("SL.mean","SL.glm"),
                        k_split = 3,
                        verbose=TRUE,
                        stratified_fit=F)$plot.p_score()$plot.ip_weights()
```

## Repeated Fitting

The `Repeated` class allows for repeated cross-fitting procedures to mitigate randomness due to data splits. This approach is recommended in machine learning-based estimation as suggested by Chernozhukov et al. (2018).

```{r repeated, eval=F}
library(SuperLearner)
library(ggplot2)

# First create a regular AIPW object
aipw_obj <- AIPW$new(Y = outcome,
                     A = exposure,
                     W = covariates, 
                     Q.SL.library = c("SL.mean","SL.glm"),
                     g.SL.library = c("SL.mean","SL.glm"),
                     k_split = 3,
                     verbose = FALSE)

# Create a repeated fitting object from the AIPW object
repeated_aipw <- Repeated$new(aipw_obj)

# Perform repeated fitting 20 times
repeated_aipw$repfit(num_reps = 20, stratified = FALSE)

# Summarize results using median-based methods
repeated_aipw$summary_median()

# You can also visualize the distribution of estimates across repetitions
estimates_df <- repeated_aipw$repeated_estimates
ggplot(estimates_df, aes(x = Estimate, fill = Estimand)) +
  geom_density(alpha = 0.5) +
  theme_minimal() +
  labs(title = "Distribution of Estimates Across Repeated Fittings",
       subtitle = "Based on 20 repetitions",
       x = "Estimate Value",
       y = "Density")
```

Setting `stratified = TRUE` in the `repfit()` function will use the stratified fitting procedure for each repetition:

```{r repeated_strat, eval=F}
# Using stratified fitting
repeated_aipw_strat <- Repeated$new(aipw_obj)
repeated_aipw_strat$repfit(num_reps = 20, stratified = TRUE)
repeated_aipw_strat$summary_median()
```

Note that the `Repeated` class also supports parallelization with `future.apply` as described below.

## Parallelization with `future.apply` and progress bar with `progressr`

In default setting, the `AIPW$fit()` method will be run sequentially. The current version of AIPW package supports parallel processing implemented by [future.apply](https://github.com/futureverse/future.apply) package under the [future](https://github.com/futureverse/future) framework. Simply use `future::plan()` to enable parallelization and `set.seed()` to take care of the random number generation (RNG) problem:

```{r parallel, eval=T}
###Additional steps for parallel processing###
# install.packages("future.apply")
library(future.apply)
future::plan(multiprocess, workers=2, gc=T)
set.seed(888)

###Same procedure for AIPW as described above###
AIPW_SL <- AIPW$new(Y = outcome,
                    A = exposure,
                    W = covariates, 
                    Q.SL.library = c("SL.mean","SL.glm"),
                    g.SL.library = c("SL.mean","SL.glm"),
                    k_split = 3,
                    verbose=TRUE)$fit()$summary()
```

Progress bar that supports parallel processing is available in the `AIPW$fit()` method through the API from [progressr](https://github.com/futureverse/progressr) package:
```{r progressr, eval=F}
library(progressr)
#define the type of progress bar
handlers("progress")
#reporting through progressr::with_progress() which is embedded in the AIPW$fit() method
with_progress({
  AIPW_SL <- AIPW$new(Y = outcome,
                    A = exposure,
                    W = covariates, 
                    Q.SL.library = c("SL.mean","SL.glm"),
                    g.SL.library = c("SL.mean","SL.glm"),
                    k_split = 3,
                    verbose=FALSE)$fit()$summary()
})
#also available for the wrapper
with_progress({
  AIPW_SL <- aipw_wrapper(Y = outcome,
                        A = exposure,
                        W = covariates, 
                        Q.SL.library = c("SL.mean","SL.glm"),
                        g.SL.library = c("SL.mean","SL.glm"),
                        k_split = 3,
                        verbose=FALSE)
})
```

## Use `tmle`/`tmle3` fitted object as input (`AIPW_tmle` class)

`AIPW_tmle` class is designed for using `tmle`/`tmle3` fitted object as input

#### 1. `tmle`

```{r tmle}
require(tmle)
require(SuperLearner)
tmle_fit <- tmle(Y = as.vector(outcome), A = as.vector(exposure),W = covariates,
                 Q.SL.library=c("SL.mean","SL.glm"),
                 g.SL.library=c("SL.mean","SL.glm"),
                 family="binomial")
tmle_fit
#extract fitted tmle object to AIPW
AIPW_tmle$
  new(A=exposure,Y=outcome,tmle_fit = tmle_fit,verbose = TRUE)$
  summary(g.bound=0.025)
```

#### 2. `tmle3` 
__New GitHub versions (after v0.6.3.1) no longer support sl3 and tmle3. If you are still interested in using the version with sl3 and tmle3 support, please install `remotes::install_github("yqzhong7/AIPW@aje_version")__

```{r tmle3, eval =FALSE}
remotes::install_github("yqzhong7/AIPW@aje_version")
library(sl3)
library(tmle3)
node_list <- list(A = "sim_A",Y = "sim_Y",W = colnames(eager_sim_obs)[-1:-2])
or_spec <- tmle_OR(baseline_level = "0",contrast_level = "1")
tmle_task <- or_spec$make_tmle_task(eager_sim_obs,node_list)
lrnr_glm <- make_learner(Lrnr_glm)
lrnr_mean <- make_learner(Lrnr_mean)
sl <- Lrnr_sl$new(learners = list(lrnr_glm,lrnr_mean))
learner_list <- list(A = sl, Y = sl)
tmle3_fit <- tmle3(or_spec, data=eager_sim_obs, node_list, learner_list)

# parse tmle3_fit into AIPW_tmle class
AIPW_tmle$
  new(A=eager_sim_obs$sim_A,Y=eager_sim_obs$sim_Y,tmle_fit = tmle3_fit,verbose = TRUE)$
  summary()
```


--------------------
### References:

Robins JM, Rotnitzky A (1995). Semiparametric efficiency in multivariate regression models with missing data. Journal of the American Statistical Association.

Chernozhukov V, Chetverikov V, Demirer M, et al (2018). Double/debiased machine learning for treatment and structural parameters. The Econometrics Journal.

Kennedy EH, Sjolander A, Small DS (2015). Semiparametric causal inference in matched cohort studies. Biometrika.

Pearl, J., 2009. Causality. Cambridge university press.


Owner

  • Name: Yongqi Zhong
  • Login: yqzhong7
  • Kind: user
  • Company: Johns Hopkins University

GitHub Events

Total
  • Issues event: 3
  • Watch event: 4
  • Push event: 24
  • Pull request event: 8
Last Year
  • Issues event: 3
  • Watch event: 4
  • Push event: 24
  • Pull request event: 8

Committers

Last synced: over 2 years ago

All Time
  • Total Commits: 127
  • Total Committers: 3
  • Avg Commits per committer: 42.333
  • Development Distribution Score (DDS): 0.197
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
YZ y****7@g****m 102
Yongqi Zhong 3****7 22
Ashley I Naimi a****i@p****u 3
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: almost 2 years ago

All Time
  • Total issues: 14
  • Total pull requests: 33
  • Average time to close issues: 3 months
  • Average time to close pull requests: about 1 hour
  • Total issue authors: 5
  • Total pull request authors: 2
  • Average comments per issue: 0.64
  • Average comments per pull request: 0.03
  • Merged pull requests: 33
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 3
  • Pull requests: 4
  • Average time to close issues: 5 days
  • Average time to close pull requests: 13 minutes
  • Issue authors: 3
  • Pull request authors: 1
  • Average comments per issue: 1.67
  • Average comments per pull request: 0.0
  • Merged pull requests: 4
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • yqzhong7 (10)
  • barracuda156 (1)
  • andrea-giovannetti (1)
  • ngreifer (1)
  • kali-alex (1)
  • zyjdhr (1)
  • Lachlan-Cribb (1)
Pull Request Authors
  • yqzhong7 (36)
  • ainaimi (3)
Top Labels
Issue Labels
enhancement (8) documentation (2)
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • cran 512 last-month
  • Total docker downloads: 21,613
  • Total dependent packages: 1
  • Total dependent repositories: 1
  • Total versions: 2
  • Total maintainers: 1
cran.r-project.org: AIPW

Augmented Inverse Probability Weighting

  • Versions: 2
  • Dependent Packages: 1
  • Dependent Repositories: 1
  • Downloads: 512 Last month
  • Docker Downloads: 21,613
Rankings
Docker downloads count: 0.6%
Forks count: 9.7%
Stargazers count: 12.9%
Average: 18.3%
Dependent repos count: 24.1%
Dependent packages count: 28.9%
Downloads: 33.6%
Maintainers (1)
Last synced: 11 months ago

Dependencies

DESCRIPTION cran
  • R >= 2.10 depends
  • R6 * imports
  • Rsolnp * imports
  • SuperLearner * imports
  • future.apply * imports
  • ggplot2 * imports
  • progressr * imports
  • sl3 * imports
  • stats * imports
  • utils * imports
  • covr * suggests
  • knitr * suggests
  • rmarkdown * suggests
  • testthat >= 2.1.0 suggests
  • tmle * suggests
  • tmle3 * suggests