From baf8a52627719395b5539560b657ef6f60bb5979 Mon Sep 17 00:00:00 2001 From: Noah Greifer Date: Sun, 3 Mar 2024 18:35:35 -0500 Subject: [PATCH] Vignette, doc, and Namespace updates --- DESCRIPTION | 9 +-- NAMESPACE | 5 -- NEWS.md | 6 +- R/SHARED.R | 8 +-- R/functions_for_processing.R | 6 +- R/weightit2ebal.R | 2 +- R/weightit2energy.R | 4 +- R/weightit2gbm.R | 6 +- R/weightit2ipt.R | 4 +- R/weightit2npcbps.R | 2 +- R/weightit2optweight.R | 2 +- R/weightit2super.R | 2 +- README.Rmd | 41 ++++++----- README.md | 70 ++++++++++--------- man/WeightIt-package.Rd | 2 +- man/get_w_from_ps.Rd | 2 +- man/method_bart.Rd | 10 +-- man/method_cbps.Rd | 18 +++-- man/method_ebal.Rd | 14 ++-- man/method_energy.Rd | 16 ++--- man/method_gbm.Rd | 20 +++--- man/method_glm.Rd | 16 ++--- man/method_ipt.Rd | 115 +++++++++++++++++++++++++++++++ man/method_npcbps.Rd | 8 +-- man/method_optweight.Rd | 10 +-- man/method_super.Rd | 20 +++--- man/sbps.Rd | 2 +- man/weightit.Rd | 6 +- man/weightitMSM.Rd | 6 +- vignettes/estimating-effects.Rmd | 2 +- 30 files changed, 279 insertions(+), 155 deletions(-) create mode 100644 man/method_ipt.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 810dfd7..e08511d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: WeightIt Type: Package Title: Weighting for Covariate Balance in Observational Studies -Version: 0.14.2.9002 +Version: 0.14.2.9003 Authors@R: c( person("Noah", "Greifer", role=c("aut", "cre"), email = "noah.greifer@gmail.com", @@ -11,7 +11,7 @@ Description: Generates balancing weights for causal effect estimation in observa binary, multi-category, or continuous point or longitudinal treatments by easing and extending the functionality of several R packages and providing in-house estimation methods. Available methods include propensity score weighting using generalized linear models, gradient - boosting machines, the covariate balancing propensity score algorithm, Bayesian additive regression trees, and + boosting machines, the covariate balancing propensity score algorithm, inverse probability tilting, Bayesian additive regression trees, and SuperLearner, and directly estimating balancing weights using entropy balancing, energy balancing, and optimization-based weights. Also allows for assessment of weights and checking of covariate balance by interfacing directly with the 'cobalt' package. See the vignette "Installing Supporting Packages" for instructions on how @@ -24,7 +24,7 @@ Imports: chk (>= 0.8.1), rlang (>= 1.1.0), crayon, backports (>= 1.4.1), - stats, utils + stats Suggests: CBPS (>= 0.18), optweight (>= 0.2.4), @@ -44,6 +44,7 @@ Suggests: gbm (>= 2.1.3), dbarts (>= 0.9-20), misaem (>= 1.0.1), + utils, knitr, rmarkdown License: GPL (>=2) @@ -53,5 +54,5 @@ URL: https://ngreifer.github.io/WeightIt/, BugReports: https://github.com/ngreifer/WeightIt/issues VignetteBuilder: knitr LazyData: true -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 Roxygen: list(markdown = TRUE) diff --git a/NAMESPACE b/NAMESPACE index b29661c..86b84b4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -33,10 +33,5 @@ import(stats) importFrom(crayon,italic) importFrom(crayon,strikethrough) importFrom(crayon,underline) -importFrom(graphics,boxplot) importFrom(graphics,hist) -importFrom(graphics,par) importFrom(graphics,plot) -importFrom(utils,combn) -importFrom(utils,data) -importFrom(utils,hasName) diff --git a/NEWS.md b/NEWS.md index 2c79490..77e2ec0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,8 @@ WeightIt News and Updates # WeightIt (development version) +* Added inverse probability tilting (IPT) as described by Graham, Pinto, and Egel (2012), which can be requested by setting `method = "ipt"`. Thus is similar to entropy balancing and CBPS in that it enforces exact balance and yields a propensity score, but has some theoretical advantages to both methods. A version is available for continuous treatments, but it should be used with caution (it is essentially the same as CBPS in this case). IPT does not rely on any other packages and runs very quickly. + * New function `calibrate()` to apply Platt scaling to calibrate propensity scores as recommended by [Gutman et al. (2022)](http://arxiv.org/abs/2211.01221). * A new argument `quantile` can be supplied to `weightit()` with all the methods that accept `moments` and `int` (`"ebal"`, `"npcbps"`, `"optweight"`, and `"energy"`). This allows one to request balance on the quantiles of the covariates, which can add some robustness as demonstrated by [Beręsewicz (2023)](https://arxiv.org/abs/2310.11969). @@ -19,7 +21,9 @@ WeightIt News and Updates * Warning messages now display immediately rather than at the end of evaluation. -* The vignettes have been changed to use a slightly different estimator for weighted g-computation. The estimated weights are no longer to be included in the call to `avg_comparisons()`, etc.; that is, they are only used to fit the outcome model. This makes the estimators more consistent with other software, including `teffects ipwra` in Stata, and most of the literature on weighted g-computation. Note this will not effect any estimates for the ATT or ATC and will only yield at most minor changes for the ATE. For other estimands, the weights are still included. +* The vignettes have been changed to use a slightly different estimator for weighted g-computation. The estimated weights are no longer to be included in the call to `avg_comparisons()`, etc.; that is, they are only used to fit the outcome model. This makes the estimators more consistent with other software, including `teffects ipwra` in Stata, and most of the literature on weighted g-computation. Note this will not effect any estimates for the ATT or ATC and will only yield at most minor changes for the ATE. For other estimands (e.g., ATO), the weights are still to be included. + +* The word "multinomial" to describe treatments with more than two categories has been replaced with "multi-category" in all documentation and messages. * Transferred all help files to Roxygen and reorganized package scripts. diff --git a/R/SHARED.R b/R/SHARED.R index 7528641..3e05fdf 100644 --- a/R/SHARED.R +++ b/R/SHARED.R @@ -196,10 +196,6 @@ strsplits <- function(x, splits, fixed = TRUE, ...) { for (split in splits) x <- unlist(strsplit(x, split, fixed = TRUE, ...)) return(x[x != ""]) # Remove empty values } -c.factor <- function(..., recursive = TRUE) { - #c() for factors - unlist(list(...), recursive = recursive) -} can_str2num <- function(x) { if (is.numeric(x) || is.logical(x)) return(TRUE) nas <- is.na(x) @@ -208,7 +204,7 @@ can_str2num <- function(x) { } str2num <- function(x) { nas <- is.na(x) - if (!is_(x, c("numeric", "logical"))) x <- as.character(x) + if (!is.numeric(x) && !is.logical(x)) x <- as.character(x) suppressWarnings(x_num <- as.numeric(x)) is.na(x_num[nas]) <- TRUE x_num @@ -473,7 +469,7 @@ bw.nrd <- function(x) { #R's bw.nrd doesn't always work, but bw.nrd0 does bw.nrd0(x)*1.06/.9 } -quantile.w <- function(x, probs = seq(0, 1, 0.25), w = NULL, na.rm = FALSE, ...) { +w.quantile <- function(x, probs = seq(0, 1, 0.25), w = NULL, na.rm = FALSE, ...) { n <- length(x) if (n == 0 || (!isTRUE(na.rm) && anyNA(x))) { diff --git a/R/functions_for_processing.R b/R/functions_for_processing.R index 2d5466e..1716cd3 100644 --- a/R/functions_for_processing.R +++ b/R/functions_for_processing.R @@ -524,7 +524,7 @@ int.poly.f <- function(d, ex = NULL, int = FALSE, poly = 1, center = TRUE, ortho out } -quantile.f <- function(d, qu = NULL, s.weights = NULL, focal = NULL, treat = NULL, const = 2000) { +quantile_f <- function(d, qu = NULL, s.weights = NULL, focal = NULL, treat = NULL, const = 2000) { # Creates new variables for use in balance quantiles. `qu` is a list of quantiles for each # continuous variable in `d`, and returns a matrix with a column for each requested quantile # of each variable, taking on 0 for values less than the quantile, .5 for values at the quantile, @@ -577,7 +577,7 @@ quantile.f <- function(d, qu = NULL, s.weights = NULL, focal = NULL, treat = NUL do.call("cbind", lapply(names(qu), function(i) { target <- if (is_null(focal)) d[,i] else d[treat == focal, i] out <- do.call("cbind", lapply(qu[[i]], function(q) { - plogis(const * (d[,i] - quantile.w(target, q, s.weights))) + plogis(const * (d[,i] - w.quantile(target, q, s.weights))) })) colnames(out) <- paste0(i, "_", qu[[i]]) @@ -993,7 +993,7 @@ get_dens_fun <- function(use.kernel = FALSE, bw = NULL, adjust = NULL, kernel = densfun } -get.w.from.ps <- function(ps, treat, estimand = "ATE", focal = NULL, subclass = NULL, stabilize = FALSE) { +.get_w_from_ps_internal <- function(ps, treat, estimand = "ATE", focal = NULL, subclass = NULL, stabilize = FALSE) { #Batch turn PS into weights; primarily for output of predict.gbm # Assumes a (0,1) treatment if binary, with ATT already processed if (is_null(dim(ps))) { diff --git a/R/weightit2ebal.R b/R/weightit2ebal.R index 7632cce..42e2ab0 100644 --- a/R/weightit2ebal.R +++ b/R/weightit2ebal.R @@ -127,7 +127,7 @@ weightit2ebal <- function(covs, treat, s.weights, subset, estimand, focal, covs <- cbind(covs, int.poly.f(covs, poly = moments, int = int, center = TRUE)) - covs <- cbind(covs, quantile.f(covs, qu = A[["quantile"]], s.weights = s.weights, + covs <- cbind(covs, quantile_f(covs, qu = A[["quantile"]], s.weights = s.weights, focal = focal, treat = treat)) for (i in seq_col(covs)) covs[,i] <- make.closer.to.1(covs[,i]) diff --git a/R/weightit2energy.R b/R/weightit2energy.R index 668c82c..4312fce 100644 --- a/R/weightit2energy.R +++ b/R/weightit2energy.R @@ -220,7 +220,7 @@ weightit2energy <- function(covs, treat, s.weights, subset, estimand, focal, mis } if (is_not_null(A[["quantile"]])) { - qu <- quantile.f(covs, qu = A[["quantile"]], s.weights = s.weights) + qu <- quantile_f(covs, qu = A[["quantile"]], s.weights = s.weights) targets <- col.w.m(qu, s.weights) @@ -256,7 +256,7 @@ weightit2energy <- function(covs, treat, s.weights, subset, estimand, focal, mis } if (is_not_null(A[["quantile"]])) { - qu <- quantile.f(covs, qu = A[["quantile"]], s.weights = s.weights, + qu <- quantile_f(covs, qu = A[["quantile"]], s.weights = s.weights, focal = focal, treat = treat) targets <- col.w.m(qu[in_focal,, drop = FALSE], s.weights[in_focal]) diff --git a/R/weightit2gbm.R b/R/weightit2gbm.R index 6f0c58f..1430ed0 100644 --- a/R/weightit2gbm.R +++ b/R/weightit2gbm.R @@ -341,7 +341,7 @@ weightit2gbm <- function(covs, treat, s.weights, estimand, focal, subset, } ps <- gbm::predict.gbm(fit, n.trees = iters.grid, type = "response", newdata = covs) - w <- get.w.from.ps(ps, treat = treat, estimand = estimand, focal = focal, stabilize = stabilize, subclass = subclass) + w <- .get_w_from_ps_internal(ps, treat = treat, estimand = estimand, focal = focal, stabilize = stabilize, subclass = subclass) if (trim.at != 0) w <- suppressMessages(apply(w, 2, trim, at = trim.at, treat = treat)) iter.grid.balance <- apply(w, 2, cobalt::bal.compute, x = init) @@ -365,7 +365,7 @@ weightit2gbm <- function(covs, treat, s.weights, estimand, focal, subset, } ps <- gbm::predict.gbm(fit, n.trees = iters.to.check, type = "response", newdata = covs) - w <- get.w.from.ps(ps, treat = treat, estimand = estimand, focal = focal, stabilize = stabilize, subclass = subclass) + w <- .get_w_from_ps_internal(ps, treat = treat, estimand = estimand, focal = focal, stabilize = stabilize, subclass = subclass) if (trim.at != 0) w <- suppressMessages(apply(w, 2, trim, at = trim.at, treat = treat)) iter.grid.balance.fine <- apply(w, 2, cobalt::bal.compute, x = init) @@ -426,7 +426,7 @@ weightit2gbm <- function(covs, treat, s.weights, estimand, focal, subset, if (best.loss < current.best.loss) { best.fit <- fit best.ps <- gbm::predict.gbm(fit, n.trees = best.tree, type = "response", newdata = covs) - best.w <- drop(get.w.from.ps(best.ps, treat = treat, estimand = estimand, focal = focal, stabilize = stabilize, subclass = subclass)) + best.w <- drop(.get_w_from_ps_internal(best.ps, treat = treat, estimand = estimand, focal = focal, stabilize = stabilize, subclass = subclass)) # if (trim.at != 0) best.w <- suppressMessages(trim(best.w, at = trim.at, treat = treat)) current.best.loss <- best.loss best.tune.index <- i diff --git a/R/weightit2ipt.R b/R/weightit2ipt.R index 99010c4..8092639 100644 --- a/R/weightit2ipt.R +++ b/R/weightit2ipt.R @@ -117,7 +117,7 @@ weightit2ipt <- function(covs, treat, s.weights, subset, estimand, focal, covs <- cbind(covs, int.poly.f(covs, poly = moments, int = int, center = TRUE)) - covs <- cbind(covs, quantile.f(covs, qu = A[["quantile"]], s.weights = s.weights, + covs <- cbind(covs, quantile_f(covs, qu = A[["quantile"]], s.weights = s.weights, focal = focal, treat = treat)) for (i in seq_col(covs)) covs[,i] <- make.closer.to.1(covs[,i]) @@ -239,7 +239,7 @@ weightit2ipt.multi <- function(covs, treat, s.weights, subset, estimand, focal, covs <- cbind(covs, int.poly.f(covs, poly = moments, int = int, center = TRUE)) - covs <- cbind(covs, quantile.f(covs, qu = A[["quantile"]], s.weights = s.weights, + covs <- cbind(covs, quantile_f(covs, qu = A[["quantile"]], s.weights = s.weights, focal = focal, treat = treat)) for (i in seq_col(covs)) covs[,i] <- make.closer.to.1(covs[,i]) diff --git a/R/weightit2npcbps.R b/R/weightit2npcbps.R index 42894a7..34a8386 100644 --- a/R/weightit2npcbps.R +++ b/R/weightit2npcbps.R @@ -108,7 +108,7 @@ weightit2npcbps <- function(covs, treat, s.weights, subset, missing, moments, in covs <- cbind(covs, int.poly.f(covs, poly = moments, int = int)) - covs <- cbind(covs, quantile.f(covs, qu = A[["quantile"]], s.weights = s.weights)) + covs <- cbind(covs, quantile_f(covs, qu = A[["quantile"]], s.weights = s.weights)) for (i in seq_col(covs)) covs[,i] <- make.closer.to.1(covs[,i]) diff --git a/R/weightit2optweight.R b/R/weightit2optweight.R index da9ad39..47c1a40 100644 --- a/R/weightit2optweight.R +++ b/R/weightit2optweight.R @@ -130,7 +130,7 @@ weightit2optweight <- function(covs, treat, s.weights, subset, estimand, focal, covs <- cbind(covs, int.poly.f(covs, poly = moments, int = int)) - covs <- cbind(covs, quantile.f(covs, qu = A[["quantile"]], s.weights = s.weights, + covs <- cbind(covs, quantile_f(covs, qu = A[["quantile"]], s.weights = s.weights, focal = focal, treat = treat)) for (i in seq_col(covs)) covs[,i] <- make.closer.to.1(covs[,i]) diff --git a/R/weightit2super.R b/R/weightit2super.R index 9abb658..05e9097 100644 --- a/R/weightit2super.R +++ b/R/weightit2super.R @@ -488,7 +488,7 @@ weightit2super.cont <- function(covs, treat, s.weights, subset, stabilize, missi Z[Z[,i] < tol, i] <- tol Z[Z[,i] > 1-tol, i] <- 1-tol } - w_mat <- get.w.from.ps(Z, treat = Y, estimand = estimand) + w_mat <- .get_w_from_ps_internal(Z, treat = Y, estimand = estimand) cvRisk <- apply(w_mat, 2, cobalt::bal.compute, x = init) names(cvRisk) <- libraryNames diff --git a/README.Rmd b/README.Rmd index b95df1f..e32e156 100644 --- a/README.Rmd +++ b/README.Rmd @@ -25,7 +25,7 @@ knitr::opts_chunk$set( ------ ### Overview -`WeightIt` is a one-stop package to generate balancing weights for point and longitudinal treatments in observational studies. Contained within `WeightIt` are methods that call on other R packages to estimate weights. The value of `WeightIt` is in its unified and familiar syntax used to generate the weights, as each of these other packages have their own, often challenging to navigate, syntax. `WeightIt` extends the capabilities of these packages to generate weights used to estimate the ATE, ATT, ATC, and other estimands for binary or multinomial treatments, and treatment effects for continuous treatments when available. In these ways, `WeightIt` does for weighting what `MatchIt` has done for matching, and `MatchIt` users will find the syntax familiar. +`WeightIt` is a one-stop package to generate balancing weights for point and longitudinal treatments in observational studies. Contained within `WeightIt` are methods that call on other R packages to estimate weights. The value of `WeightIt` is in its unified and familiar syntax used to generate the weights, as each of these other packages have their own, often challenging to navigate, syntax. `WeightIt` extends the capabilities of these packages to generate weights used to estimate the ATE, ATT, ATC, and other estimands for binary or multi-category treatments, and treatment effects for continuous treatments when available. In these ways, `WeightIt` does for weighting what `MatchIt` has done for matching, and `MatchIt` users will find the syntax familiar. For a complete vignette, see the [website](https://ngreifer.github.io/WeightIt/articles/WeightIt.html) for `WeightIt` or `vignette("WeightIt")`. @@ -78,31 +78,34 @@ The table below contains the available methods in `WeightIt` for estimating weig -------------- | -------------------- | -------- **Binary** | Binary regression PS (`"glm"`) | various - | Generalized boosted modeling PS (`"gbm"`) | `gbm` - - | Covariate Balancing PS (`"cbps"`) | `CBPS` - - | Non-Parametric Covariate Balancing PS (`"npcbps"`) | `CBPS` + - | Covariate balancing PS (`"cbps"`) | `CBPS` + - | Non-parametric covariate balancing PS (`"npcbps"`) | `CBPS` - | Entropy Balancing (`"ebal"`) | - - - | Optimization-Based Weights (`"optweight"`) | `optweight` + - | Inverse probability tilting (`"ipt"`) | - + - | Optimization-based Weights (`"optweight"`) | `optweight` - | SuperLearner PS (`"super"`) | `SuperLearner` - - | Bayesian Additive Regression Trees PS (`"bart"`) | `dbarts` - - | Energy Balancing (`"energy"`) | - - **Multinomial** | Multinomial regression PS (`"glm"`) | various + - | Bayesian additive regression trees PS (`"bart"`) | `dbarts` + - | Energy balancing (`"energy"`) | - + **Multi-categoryl** | Multinomial regression PS (`"glm"`) | various - | Generalized boosted modeling PS (`"gbm"`) | `gbm` - - | Covariate Balancing PS (`"cbps"`) | `CBPS` - - | Non-Parametric Covariate Balancing PS (`"npcbps"`) | `CBPS` - - | Entropy Balancing (`"ebal"`) | - - - | Optimization-Based Weights (`"optweight"`) | `optweight` + - | Covariate balancing PS (`"cbps"`) | `CBPS` + - | Non-Parametric covariate balancing PS (`"npcbps"`) | `CBPS` + - | Entropy balancing (`"ebal"`) | - + - | Inverse probability tilting (`"ipt"`) | - + - | Optimization-based weights (`"optweight"`) | `optweight` - | SuperLearner PS (`"super"`) | `SuperLearner` - - | Bayesian Additive Regression Trees PS (`"bart"`) | `dbarts` - - | Energy Balancing (`"energy"`) | - + - | Bayesian additive regression trees PS (`"bart"`) | `dbarts` + - | Energy balancing (`"energy"`) | - **Continuous** | Generalized linear model GPS (`"glm"`) | - - | Generalized boosted modeling GPS (`"gbm"`) | `gbm` - - | Covariate Balancing GPS (`"cbps"`) | `CBPS` - - | Non-Parametric Covariate Balancing GPS (`"npcbps"`) | `CBPS` - - | Entropy Balancing (`"ebal"`) | - - - | Optimization-Based Weights (`"optweight"`) | `optweight` + - | Covariate balancing GPS (`"cbps"`) | `CBPS` + - | Non-Parametric covariate balancing GPS (`"npcbps"`) | `CBPS` + - | Entropy balancing (`"ebal"`) | - + - | Inverse probability tilting (`"ipt"`) | - + - | Optimization-based weights (`"optweight"`) | `optweight` - | SuperLearner GPS (`"super"`) | `SuperLearner` - - | Bayesian Additive Regression Trees GPS (`"bart"`) | `dbarts` - - | Distance Covariance Optimal Weighting (`"energy"`) | - + - | Bayesian additive regression trees GPS (`"bart"`) | `dbarts` + - | Distance covariance optimal weighting (`"energy"`) | - In addition, `WeightIt` implements the subgroup balancing propensity score using the function `sbps()`. Several other tools and utilities are available. diff --git a/README.md b/README.md index b926560..2213901 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,11 @@ weights. The value of `WeightIt` is in its unified and familiar syntax used to generate the weights, as each of these other packages have their own, often challenging to navigate, syntax. `WeightIt` extends the capabilities of these packages to generate weights used to estimate the -ATE, ATT, ATC, and other estimands for binary or multinomial treatments, -and treatment effects for continuous treatments when available. In these -ways, `WeightIt` does for weighting what `MatchIt` has done for -matching, and `MatchIt` users will find the syntax familiar. +ATE, ATT, ATC, and other estimands for binary or multi-category +treatments, and treatment effects for continuous treatments when +available. In these ways, `WeightIt` does for weighting what `MatchIt` +has done for matching, and `MatchIt` users will find the syntax +familiar. For a complete vignette, see the [website](https://ngreifer.github.io/WeightIt/articles/WeightIt.html) @@ -139,35 +140,38 @@ using various methods and functions from various packages. See `vignette("installing-packages")` for information on how to install these packages. -| Treatment type | Method (`method =`) | Package | -|-----------------|-----------------------------------------------------|----------------| -| **Binary** | Binary regression PS (`"glm"`) | various | -| \- | Generalized boosted modeling PS (`"gbm"`) | `gbm` | -| \- | Covariate Balancing PS (`"cbps"`) | `CBPS` | -| \- | Non-Parametric Covariate Balancing PS (`"npcbps"`) | `CBPS` | -| \- | Entropy Balancing (`"ebal"`) | \- | -| \- | Optimization-Based Weights (`"optweight"`) | `optweight` | -| \- | SuperLearner PS (`"super"`) | `SuperLearner` | -| \- | Bayesian Additive Regression Trees PS (`"bart"`) | `dbarts` | -| \- | Energy Balancing (`"energy"`) | \- | -| **Multinomial** | Multinomial regression PS (`"glm"`) | various | -| \- | Generalized boosted modeling PS (`"gbm"`) | `gbm` | -| \- | Covariate Balancing PS (`"cbps"`) | `CBPS` | -| \- | Non-Parametric Covariate Balancing PS (`"npcbps"`) | `CBPS` | -| \- | Entropy Balancing (`"ebal"`) | \- | -| \- | Optimization-Based Weights (`"optweight"`) | `optweight` | -| \- | SuperLearner PS (`"super"`) | `SuperLearner` | -| \- | Bayesian Additive Regression Trees PS (`"bart"`) | `dbarts` | -| \- | Energy Balancing (`"energy"`) | \- | -| **Continuous** | Generalized linear model GPS (`"glm"`) | \- | -| \- | Generalized boosted modeling GPS (`"gbm"`) | `gbm` | -| \- | Covariate Balancing GPS (`"cbps"`) | `CBPS` | -| \- | Non-Parametric Covariate Balancing GPS (`"npcbps"`) | `CBPS` | -| \- | Entropy Balancing (`"ebal"`) | \- | -| \- | Optimization-Based Weights (`"optweight"`) | `optweight` | -| \- | SuperLearner GPS (`"super"`) | `SuperLearner` | -| \- | Bayesian Additive Regression Trees GPS (`"bart"`) | `dbarts` | -| \- | Distance Covariance Optimal Weighting (`"energy"`) | \- | +| Treatment type | Method (`method =`) | Package | +|---------------------|-----------------------------------------------------|----------------| +| **Binary** | Binary regression PS (`"glm"`) | various | +| \- | Generalized boosted modeling PS (`"gbm"`) | `gbm` | +| \- | Covariate balancing PS (`"cbps"`) | `CBPS` | +| \- | Non-parametric covariate balancing PS (`"npcbps"`) | `CBPS` | +| \- | Entropy Balancing (`"ebal"`) | \- | +| \- | Inverse probability tilting (`"ipt"`) | \- | +| \- | Optimization-based Weights (`"optweight"`) | `optweight` | +| \- | SuperLearner PS (`"super"`) | `SuperLearner` | +| \- | Bayesian additive regression trees PS (`"bart"`) | `dbarts` | +| \- | Energy balancing (`"energy"`) | \- | +| **Multi-categoryl** | Multinomial regression PS (`"glm"`) | various | +| \- | Generalized boosted modeling PS (`"gbm"`) | `gbm` | +| \- | Covariate balancing PS (`"cbps"`) | `CBPS` | +| \- | Non-Parametric covariate balancing PS (`"npcbps"`) | `CBPS` | +| \- | Entropy balancing (`"ebal"`) | \- | +| \- | Inverse probability tilting (`"ipt"`) | \- | +| \- | Optimization-based weights (`"optweight"`) | `optweight` | +| \- | SuperLearner PS (`"super"`) | `SuperLearner` | +| \- | Bayesian additive regression trees PS (`"bart"`) | `dbarts` | +| \- | Energy balancing (`"energy"`) | \- | +| **Continuous** | Generalized linear model GPS (`"glm"`) | \- | +| \- | Generalized boosted modeling GPS (`"gbm"`) | `gbm` | +| \- | Covariate balancing GPS (`"cbps"`) | `CBPS` | +| \- | Non-Parametric covariate balancing GPS (`"npcbps"`) | `CBPS` | +| \- | Entropy balancing (`"ebal"`) | \- | +| \- | Inverse probability tilting (`"ipt"`) | \- | +| \- | Optimization-based weights (`"optweight"`) | `optweight` | +| \- | SuperLearner GPS (`"super"`) | `SuperLearner` | +| \- | Bayesian additive regression trees GPS (`"bart"`) | `dbarts` | +| \- | Distance covariance optimal weighting (`"energy"`) | \- | In addition, `WeightIt` implements the subgroup balancing propensity score using the function `sbps()`. Several other tools and utilities are diff --git a/man/WeightIt-package.Rd b/man/WeightIt-package.Rd index b124555..2bab150 100644 --- a/man/WeightIt-package.Rd +++ b/man/WeightIt-package.Rd @@ -8,7 +8,7 @@ \description{ \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} -Generates balancing weights for causal effect estimation in observational studies with binary, multi-category, or continuous point or longitudinal treatments by easing and extending the functionality of several R packages and providing in-house estimation methods. Available methods include propensity score weighting using generalized linear models, gradient boosting machines, the covariate balancing propensity score algorithm, Bayesian additive regression trees, and SuperLearner, and directly estimating balancing weights using entropy balancing, energy balancing, and optimization-based weights. Also allows for assessment of weights and checking of covariate balance by interfacing directly with the 'cobalt' package. See the vignette "Installing Supporting Packages" for instructions on how to install any package 'WeightIt' uses, including those that may not be on CRAN. +Generates balancing weights for causal effect estimation in observational studies with binary, multi-category, or continuous point or longitudinal treatments by easing and extending the functionality of several R packages and providing in-house estimation methods. Available methods include propensity score weighting using generalized linear models, gradient boosting machines, the covariate balancing propensity score algorithm, inverse probability tilting, Bayesian additive regression trees, and SuperLearner, and directly estimating balancing weights using entropy balancing, energy balancing, and optimization-based weights. Also allows for assessment of weights and checking of covariate balance by interfacing directly with the 'cobalt' package. See the vignette "Installing Supporting Packages" for instructions on how to install any package 'WeightIt' uses, including those that may not be on CRAN. } \seealso{ Useful links: diff --git a/man/get_w_from_ps.Rd b/man/get_w_from_ps.Rd index 41dfc59..23c9f1c 100644 --- a/man/get_w_from_ps.Rd +++ b/man/get_w_from_ps.Rd @@ -201,7 +201,7 @@ Approach for Confounding Adjustment When Exposure Is Infrequent: Epidemiology, 28(2), 249–257. \doi{10.1097/EDE.0000000000000595} } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ \itemize{ \item \code{estimand = "ATO"} } diff --git a/man/method_bart.Rd b/man/method_bart.Rd index 30eeb48..ceb3a20 100644 --- a/man/method_bart.Rd +++ b/man/method_bart.Rd @@ -4,7 +4,7 @@ \alias{method_bart} \title{Propensity Score Weighting Using BART} \description{ -This page explains the details of estimating weights from Bayesian additive regression trees (BART)-based propensity scores by setting \code{method = "bart"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. +This page explains the details of estimating weights from Bayesian additive regression trees (BART)-based propensity scores by setting \code{method = "bart"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. In general, this method relies on estimating propensity scores using BART and then converting those propensity scores into weights using a formula that depends on the desired estimand. This method relies on \pkgfun2{dbarts}{bart}{dbarts::bart2} from the \CRANpkg{dbarts} package. \subsection{Binary Treatments}{ @@ -12,9 +12,9 @@ In general, this method relies on estimating propensity scores using BART and th For binary treatments, this method estimates the propensity scores using \pkgfun2{dbarts}{bart}{dbarts::bart2}. The following estimands are allowed: ATE, ATT, ATC, ATO, ATM, and ATOS. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ -For multinomial treatments, the propensity scores are estimated using several calls to \pkgfun2{dbarts}{bart}{dbarts::bart2}, one for each treatment group; the treatment probabilities are not normalized to sum to 1. The following estimands are allowed: ATE, ATT, ATC, ATO, and ATM. The weights for each estimand are computed using the standard formulas or those mentioned above. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. +For multi-category treatments, the propensity scores are estimated using several calls to \pkgfun2{dbarts}{bart}{dbarts::bart2}, one for each treatment group; the treatment probabilities are not normalized to sum to 1. The following estimands are allowed: ATE, ATT, ATC, ATO, and ATM. The weights for each estimand are computed using the standard formulas or those mentioned above. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. } \subsection{Continuous Treatments}{ @@ -72,7 +72,7 @@ For continuous treatments only, the following arguments may be supplied: \describe{ \item{\code{obj}}{ -When \code{include.obj = TRUE}, the \code{bart2} fit(s) used to generate the predicted values. With multinomial treatments, this will be a list of the fits; otherwise, it will be a single fit. The predicted probabilities used to compute the propensity scores can be extracted using \pkgfun2{dbarts}{bart}{fitted}. +When \code{include.obj = TRUE}, the \code{bart2} fit(s) used to generate the predicted values. With multi-category treatments, this will be a list of the fits; otherwise, it will be a single fit. The predicted probabilities used to compute the propensity scores can be extracted using \pkgfun2{dbarts}{bart}{fitted}. } } } @@ -89,7 +89,7 @@ data("lalonde", package = "cobalt") summary(W1) bal.tab(W1) \donttest{ -#Balancing covariates with respect to race (multinomial) +#Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "bart", estimand = "ATE")) diff --git a/man/method_cbps.Rd b/man/method_cbps.Rd index 6b21d6a..df6acae 100644 --- a/man/method_cbps.Rd +++ b/man/method_cbps.Rd @@ -4,7 +4,7 @@ \alias{method_cbps} \title{Covariate Balancing Propensity Score Weighting} \description{ -This page explains the details of estimating weights from covariate balancing propensity scores by setting \code{method = "cbps"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. +This page explains the details of estimating weights from covariate balancing propensity scores by setting \code{method = "cbps"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. In general, this method relies on estimating propensity scores using generalized method of moments and then converting those propensity scores into weights using a formula that depends on the desired estimand. This method relies on \pkgfun{CBPS}{CBPS} from the \CRANpkg{CBPS} package. \subsection{Binary Treatments}{ @@ -12,9 +12,9 @@ In general, this method relies on estimating propensity scores using generalized For binary treatments, this method estimates the propensity scores and weights using \pkgfun{CBPS}{CBPS}. The following estimands are allowed: ATE, ATT, and ATC. The weights are taken from the output of the \code{CBPS} fit object. When the estimand is the ATE, the return propensity score is the probability of being in the "second" treatment group, i.e., \code{levels(factor(treat))[2]}; when the estimand is the ATC, the returned propensity score is the probability of being in the control (i.e., non-focal) group. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ -For multinomial treatments with three or four categories and when the estimand is the ATE, this method estimates the propensity scores and weights using one call to \pkgfun{CBPS}{CBPS}. For multinomial treatments with three or four categories or when the estimand is the ATT, this method estimates the propensity scores and weights using multiple calls to \pkgfun{CBPS}{CBPS}. The following estimands are allowed: ATE and ATT. The weights are taken from the output of the \code{CBPS} fit objects. +For multi-category treatments with three or four categories and when the estimand is the ATE, this method estimates the propensity scores and weights using one call to \pkgfun{CBPS}{CBPS}. For multi-category treatments with three or four categories or when the estimand is the ATT, this method estimates the propensity scores and weights using multiple calls to \pkgfun{CBPS}{CBPS}. The following estimands are allowed: ATE and ATT. The weights are taken from the output of the \code{CBPS} fit objects. } \subsection{Continuous Treatments}{ @@ -43,7 +43,9 @@ First, for each variable with missingness, a new missingness indicator variable } } \details{ -CBPS estimates the coefficients of a logistic regression model (for binary treatments), multinomial logistic regression model (form multinomial treatments), or linear regression model (for continuous treatments) that is used to compute (generalized) propensity scores, from which the weights are computed. It involves augmenting the standard regression score equations with the balance constraints in an over-identified generalized method of moments estimation. The idea is to nudge the estimation of the coefficients toward those that produce balance in the weighted sample. The just-identified version (with \code{exact = FALSE}) does away with the score equations for the coefficients so that only the balance constraints (and the score equation for the variance of the error with a continuous treatment) are used. The just-identified version will therefore produce superior balance on the means (i.e., corresponding to the balance constraints) for binary and multinomial treatments and linear terms for continuous treatments than will the over-identified version. +CBPS estimates the coefficients of a logistic regression model (for binary treatments), multinomial logistic regression model (form multi-category treatments), or linear regression model (for continuous treatments) that is used to compute (generalized) propensity scores, from which the weights are computed. It involves augmenting the standard regression score equations with the balance constraints in an over-identified generalized method of moments estimation. The idea is to nudge the estimation of the coefficients toward those that produce balance in the weighted sample. The just-identified version (with \code{exact = FALSE}) does away with the score equations for the coefficients so that only the balance constraints (and the score equation for the variance of the error with a continuous treatment) are used. The just-identified version will therefore produce superior balance on the means (i.e., corresponding to the balance constraints) for binary and multi-category treatments and linear terms for continuous treatments than will the over-identified version. + +Just-identified CBPS is very similar to entropy balancing and inverse probability tilting. For the ATT, all three methods will yield identical estimates. For other estimands, the results will differ. Note that \pkg{WeightIt} provides less functionality than does the \pkg{CBPS} package in terms of the versions of CBPS available; for extensions to CBPS, the \pkg{CBPS} package may be preferred. } @@ -65,7 +67,7 @@ All arguments take on the defaults of those in \code{CBPS()}. It may be useful i \section{Additional Outputs}{ \describe{ -\item{\code{obj}}{When \code{include.obj = TRUE}, the CB(G)PS model fit. For binary treatments, multinomial treatments with \code{estimand = "ATE"} and four or fewer treatment levels, and continuous treatments, the output of the call to \pkgfun{CBPS}{CBPS}. For multinomial treatments with \code{estimand = "ATT"} or with more than four treatment levels, a list of \code{CBPS} fit objects. +\item{\code{obj}}{When \code{include.obj = TRUE}, the CB(G)PS model fit. For binary treatments, multi-category treatments with \code{estimand = "ATE"} and four or fewer treatment levels, and continuous treatments, the output of the call to \pkgfun{CBPS}{CBPS}. For multi-category treatments with \code{estimand = "ATT"} or with more than four treatment levels, a list of \code{CBPS} fit objects. } } } @@ -83,7 +85,7 @@ summary(W1) bal.tab(W1) \dontrun{ - #Balancing covariates with respect to race (multinomial) + #Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "cbps", estimand = "ATE")) @@ -105,7 +107,7 @@ bal.tab(W3) Imai, K., & Ratkovic, M. (2014). Covariate balancing propensity score. Journal of the Royal Statistical Society: Series B (Statistical Methodology), 76(1), 243–263. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ Imai, K., & Ratkovic, M. (2014). Covariate balancing propensity score. Journal of the Royal Statistical Society: Series B (Statistical Methodology), 76(1), 243–263. } @@ -118,5 +120,7 @@ Fong, C., Hazlett, C., & Imai, K. (2018). Covariate balancing propensity score f \seealso{ \code{\link[=weightit]{weightit()}}, \code{\link[=weightitMSM]{weightitMSM()}} +\link{method_ebal} and \link{method_ipt} for entropy balancing and inverse probability tilting, which work similarly. + \pkgfun{CBPS}{CBPS} for the fitting function. } diff --git a/man/method_ebal.Rd b/man/method_ebal.Rd index b98b2a6..c7084f4 100644 --- a/man/method_ebal.Rd +++ b/man/method_ebal.Rd @@ -4,7 +4,7 @@ \alias{method_ebal} \title{Entropy Balancing} \description{ -This page explains the details of estimating weights using entropy balancing by setting \code{method = "ebal"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. +This page explains the details of estimating weights using entropy balancing by setting \code{method = "ebal"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. In general, this method relies on estimating weights by minimizing the negative entropy of the weights subject to exact moment balancing constraints. This method relies on code written for \pkg{WeightIt} using \code{\link[=optim]{optim()}}. \subsection{Binary Treatments}{ @@ -12,9 +12,9 @@ In general, this method relies on estimating weights by minimizing the negative For binary treatments, this method estimates the weights using \code{optim()} using formulas described by Hainmueller (2012). The following estimands are allowed: ATE, ATT, and ATC. When the ATE is requested, the optimization is run twice, once for each treatment group. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ -For multinomial treatments, this method estimates the weights using \code{optim()}. The following estimands are allowed: ATE and ATT. When the ATE is requested, \code{optim()} is run once for each treatment group. When the ATT is requested, \code{optim()} is run once for each non-focal (i.e., control) group. +For multi-category treatments, this method estimates the weights using \code{optim()}. The following estimands are allowed: ATE and ATT. When the ATE is requested, \code{optim()} is run once for each treatment group. When the ATT is requested, \code{optim()} is run once for each non-focal (i.e., control) group. } \subsection{Continuous Treatments}{ @@ -43,7 +43,7 @@ First, for each variable with missingness, a new missingness indicator variable } } \details{ -Entropy balancing involves the specification of an optimization problem, the solution to which is then used to compute the weights. The constraints of the primal optimization problem correspond to covariate balance on the means (for binary and multinomial treatments) or treatment-covariate covariances (for continuous treatments), positivity of the weights, and that the weights sum to a certain value. It turns out that the dual optimization problem is much easier to solve because it is over only as many variables as there are balance constraints rather than over the weights for each unit and it is unconstrained. Zhao and Percival (2017) found that entropy balancing for the ATT of a binary treatment actually involves the estimation of the coefficients of a logistic regression propensity score model but using a specialized loss function different from that optimized with maximum likelihood. Entropy balancing is doubly robust (for the ATT) in the sense that it is consistent either when the true propensity score model is a logistic regression of the treatment on the covariates or when the true outcome model for the control units is a linear regression of the outcome on the covariates, and it attains a semi-parametric efficiency bound when both are true. Entropy balancing will always yield exact mean balance on the included terms. +Entropy balancing involves the specification of an optimization problem, the solution to which is then used to compute the weights. The constraints of the primal optimization problem correspond to covariate balance on the means (for binary and multi-category treatments) or treatment-covariate covariances (for continuous treatments), positivity of the weights, and that the weights sum to a certain value. It turns out that the dual optimization problem is much easier to solve because it is over only as many variables as there are balance constraints rather than over the weights for each unit and it is unconstrained. Zhao and Percival (2017) found that entropy balancing for the ATT of a binary treatment actually involves the estimation of the coefficients of a logistic regression propensity score model but using a specialized loss function different from that optimized with maximum likelihood. Entropy balancing is doubly robust (for the ATT) in the sense that it is consistent either when the true propensity score model is a logistic regression of the treatment on the covariates or when the true outcome model for the control units is a linear regression of the outcome on the covariates, and it attains a semi-parametric efficiency bound when both are true. Entropy balancing will always yield exact mean balance on the included terms. } \section{Additional Arguments}{ @@ -69,7 +69,7 @@ The \code{stabilize} argument is ignored; in the past it would reduce the variab \section{Additional Outputs}{ \describe{ -\item{\code{obj}}{When \code{include.obj = TRUE}, the output of the call to \code{\link[=optim]{optim()}}, which contains the dual variables and convergence information. For ATE fits or with multinomial treatments, a list of \code{optim()} outputs, one for each weighted group. +\item{\code{obj}}{When \code{include.obj = TRUE}, the output of the call to \code{\link[=optim]{optim()}}, which contains the dual variables and convergence information. For ATE fits or with multi-category treatments, a list of \code{optim()} outputs, one for each weighted group. } } } @@ -84,7 +84,7 @@ data("lalonde", package = "cobalt") summary(W1) cobalt::bal.tab(W1) -#Balancing covariates with respect to race (multinomial) +#Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "ebal", estimand = "ATE")) @@ -120,4 +120,6 @@ Vegetabile, B. G., Griffin, B. A., Coffman, D. L., Cefalu, M., Robbins, M. W., & } \seealso{ \code{\link[=weightit]{weightit()}}, \code{\link[=weightitMSM]{weightitMSM()}} + +\link{method_ipt} and \link{method_cbps} for inverse probability tilting and CBPS, which work similarly. } diff --git a/man/method_energy.Rd b/man/method_energy.Rd index 27e3294..7f1dab6 100644 --- a/man/method_energy.Rd +++ b/man/method_energy.Rd @@ -4,17 +4,17 @@ \alias{method_energy} \title{Energy Balancing} \description{ -This page explains the details of estimating weights using energy balancing by setting \code{method = "energy"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. +This page explains the details of estimating weights using energy balancing by setting \code{method = "energy"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. -In general, this method relies on estimating weights by minimizing an energy statistic related to covariate balance. For binary and multinomial treatments, this is the energy distance, which is a multivariate distance between distributions, between treatment groups. For continuous treatments, this is the sum of the distance covariance between the treatment variable and the covariates and the energy distances between the treatment and covariates in the weighted sample and their distributions in the original sample. This method relies on code written for \pkg{WeightIt} using \pkgfun{osqp}{osqp} from the \CRANpkg{osqp} package to perform the optimization. This method may be slow or memory-intensive for large datasets. +In general, this method relies on estimating weights by minimizing an energy statistic related to covariate balance. For binary and multi-category treatments, this is the energy distance, which is a multivariate distance between distributions, between treatment groups. For continuous treatments, this is the sum of the distance covariance between the treatment variable and the covariates and the energy distances between the treatment and covariates in the weighted sample and their distributions in the original sample. This method relies on code written for \pkg{WeightIt} using \pkgfun{osqp}{osqp} from the \CRANpkg{osqp} package to perform the optimization. This method may be slow or memory-intensive for large datasets. \subsection{Binary Treatments}{ For binary treatments, this method estimates the weights using \code{osqp()} using formulas described by Huling and Mak (2022). The following estimands are allowed: ATE, ATT, and ATC. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ -For multinomial treatments, this method estimates the weights using \code{osqp()} using formulas described by Huling and Mak (2022). The following estimands are allowed: ATE and ATT. +For multi-category treatments, this method estimates the weights using \code{osqp()} using formulas described by Huling and Mak (2022). The following estimands are allowed: ATE and ATT. } \subsection{Continuous Treatments}{ @@ -65,7 +65,7 @@ The following following additional arguments can be specified: \item{\code{lambda}}{a positive numeric scalar used to penalize the square of the weights. This value divided by the square of the total sample size is added to the diagonal of the quadratic part of the loss function. Higher values favor weights with less variability. Note this is distinct from the lambda value described in Huling and Mak (2022), which penalizes the complexity of individual treatment rules rather than the weights, but does correspond to lambda from Huling et al. (2021). Default is .0001, which is essentially 0. } } -For binary and multinomial treatments, the following additional arguments can be specified: +For binary and multi-category treatments, the following additional arguments can be specified: \describe{ \item{\code{improved}}{\code{logical}; whether to use the improved energy balancing weights as described by Huling and Mak (2022) when \code{estimand = "ATE"}. This involves optimizing balance not only between each treatment group and the overall sample, but also between each pair of treatment groups. Huling and Mak (2022) found that the improved energy balancing weights generally outperformed standard energy balancing. Default is \code{TRUE}; set to \code{FALSE} to use the standard energy balancing weights instead (not recommended). } @@ -84,7 +84,7 @@ The number of moments of the treatment and covariate distributions that are cons } } -The \code{moments} argument functions differently for \code{method = "energy"} from how it does with other methods. When unspecified or set to zero, energy balancing weights are estimated as described by Huling and Mak (2022) for binary and multi-category treatments or by Huling et al. (2023) for continuous treatments. When \code{moments} is set to an integer larger than 0, additional balance constraints on the requested moments of the covariates are also included, guaranteeing exact moment balance on these covariates while minimizing the energy distance of the weighted sample. For binary and multinomial treatments, this involves exact balance on the means of the entered covariates; for continuous treatments, this involves exact balance on the treatment-covariate correlations of the entered covariates. +The \code{moments} argument functions differently for \code{method = "energy"} from how it does with other methods. When unspecified or set to zero, energy balancing weights are estimated as described by Huling and Mak (2022) for binary and multi-category treatments or by Huling et al. (2023) for continuous treatments. When \code{moments} is set to an integer larger than 0, additional balance constraints on the requested moments of the covariates are also included, guaranteeing exact moment balance on these covariates while minimizing the energy distance of the weighted sample. For binary and multi-category treatments, this involves exact balance on the means of the entered covariates; for continuous treatments, this involves exact balance on the treatment-covariate correlations of the entered covariates. } \section{Additional Outputs}{ @@ -109,7 +109,7 @@ data("lalonde", package = "cobalt") summary(W1) bal.tab(W1) - #Balancing covariates with respect to race (multinomial) + #Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "energy", estimand = "ATT", @@ -127,7 +127,7 @@ data("lalonde", package = "cobalt") \dontshow{\}) # examplesIf} } \references{ -\subsection{Binary and Multinomial treatments}{ +\subsection{Binary and multi-category treatments}{ Huling, J. D., & Mak, S. (2022). Energy Balancing of Covariate Distributions (arXiv:2004.13962). arXiv. \doi{10.48550/arXiv.2004.13962} } diff --git a/man/method_gbm.Rd b/man/method_gbm.Rd index 59955e5..1d9d799 100644 --- a/man/method_gbm.Rd +++ b/man/method_gbm.Rd @@ -4,7 +4,7 @@ \alias{method_gbm} \title{Propensity Score Weighting Using Generalized Boosted Models} \description{ -This page explains the details of estimating weights from generalized boosted model-based propensity scores by setting \code{method = "gbm"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. +This page explains the details of estimating weights from generalized boosted model-based propensity scores by setting \code{method = "gbm"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. In general, this method relies on estimating propensity scores using generalized boosted modeling and then converting those propensity scores into weights using a formula that depends on the desired estimand. The algorithm involves using a balance-based or prediction-based criterion to optimize in choosing the value of tuning parameters (the number of trees and possibly others). The method relies on the \CRANpkg{gbm} package. @@ -14,7 +14,7 @@ This method mimics the functionality of functions in the \pkg{twang} package, bu For binary treatments, this method estimates the propensity scores using \pkgfun{gbm}{gbm.fit} and then selects the optimal tuning parameter values using the method specified in the \code{criterion} argument. The following estimands are allowed: ATE, ATT, ATC, ATO, and ATM. The weights are computed from the estimated propensity scores using \code{\link[=get_w_from_ps]{get_w_from_ps()}}, which implements the standard formulas. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ For binary treatments, this method estimates the propensity scores using \pkgfun{gbm}{gbm.fit} and then selects the optimal tuning parameter values using the method specified in the \code{criterion} argument. The following estimands are allowed: ATE, ATT, ATC, ATO, and ATM. The weights are computed from the estimated propensity scores using \code{\link[=get_w_from_ps]{get_w_from_ps()}}, which implements the standard formulas. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. } @@ -46,7 +46,7 @@ In the presence of missing data, the following value(s) for \code{missing} are a \details{ Generalized boosted modeling (GBM, also known as gradient boosting machines) is a machine learning method that generates predicted values from a flexible regression of the treatment on the covariates, which are treated as propensity scores and used to compute weights. It does this by building a series of regression trees, each fit to the residuals of the last, minimizing a loss function that depends on the distribution chosen. The optimal number of trees is a tuning parameter that must be chosen; McCaffrey et al. (2004) were innovative in using covariate balance to select this value rather than traditional machine learning performance metrics such as cross-validation accuracy. GBM is particularly effective for fitting nonlinear treatment models characterized by curves and interactions, but performs worse for simpler treatment models. It is unclear which balance measure should be used to select the number of trees, though research has indicated that balance measures tend to perform better than cross-validation accuracy for estimating effective propensity score weights. -\pkg{WeightIt} offers almost identical functionality to \pkg{twang}, the first package to implement this method. Compared to the current version of \pkg{twang}, \pkg{WeightIt} offers more options for the measure of balance used to select the number of trees, improved performance, tuning of hyperparameters, more estimands, and support for continuous treatments. \pkg{WeightIt} computes weights for multinomial treatments differently from how \pkg{twang} does; rather than fitting a separate binary GBM for each pair of treatments, \pkg{WeightIt} fits a single multi-class GBM model and uses balance measures appropriate for multinomial treatments. +\pkg{WeightIt} offers almost identical functionality to \pkg{twang}, the first package to implement this method. Compared to the current version of \pkg{twang}, \pkg{WeightIt} offers more options for the measure of balance used to select the number of trees, improved performance, tuning of hyperparameters, more estimands, and support for continuous treatments. \pkg{WeightIt} computes weights for multi-category treatments differently from how \pkg{twang} does; rather than fitting a separate binary GBM for each pair of treatments, \pkg{WeightIt} fits a single multi-class GBM model and uses balance measures appropriate for multi-category treatments. } \note{ The \code{criterion} argument used to be called \code{stop.method}, which is its name in \pkg{twang}. \code{stop.method} still works for backward compatibility. Additionally, the criteria formerly named as \code{es.mean}, \code{es.max}, and \code{es.rms} have been renamed to \code{smd.mean}, \code{smd.max}, and \code{smd.rms}. The former are used in \pkg{twang} and will still work with \code{weightit()} for backward compatibility. @@ -55,19 +55,19 @@ The \code{criterion} argument used to be called \code{stop.method}, which is its The following additional arguments can be specified: \describe{ -\item{\code{criterion}}{A string describing the balance criterion used to select the best weights. See \pkgfun{cobalt}{bal.compute} for allowable options for each treatment type. In addition, to optimize the cross-validation error instead of balance, \code{criterion} can be set as \verb{"cv\{#\}}", where \verb{\{#\}} is replaced by a number representing the number of cross-validation folds used (e.g., \code{"cv5"} for 5-fold cross-validation). For binary and multinomial treatments, the default is \code{"smd.mean"}, which minimizes the average absolute standard mean difference among the covariates between treatment groups. For continuous treatments, the default is \code{"p.mean"}, which minimizes the average absolute Pearson correlation between the treatment and covariates. +\item{\code{criterion}}{A string describing the balance criterion used to select the best weights. See \pkgfun{cobalt}{bal.compute} for allowable options for each treatment type. In addition, to optimize the cross-validation error instead of balance, \code{criterion} can be set as \verb{"cv\{#\}}", where \verb{\{#\}} is replaced by a number representing the number of cross-validation folds used (e.g., \code{"cv5"} for 5-fold cross-validation). For binary and multi-category treatments, the default is \code{"smd.mean"}, which minimizes the average absolute standard mean difference among the covariates between treatment groups. For continuous treatments, the default is \code{"p.mean"}, which minimizes the average absolute Pearson correlation between the treatment and covariates. } \item{\code{trim.at}}{A number supplied to \code{at} in \code{\link[=trim]{trim()}} which trims the weights from all the trees before choosing the best tree. This can be valuable when some weights are extreme, which occurs especially with continuous treatments. The default is 0 (i.e., no trimming). } -\item{\code{distribution}}{A string with the distribution used in the loss function of the boosted model. This is supplied to the \code{distribution} argument in \pkgfun{gbm}{gbm.fit}. For binary treatments, \code{"bernoulli"} and \code{"adaboost"} are available, with \code{"bernoulli"} the default. For multinomial treatments, only \code{"multinomial"} is allowed. For continuous treatments \code{"gaussian"}, \code{"laplace"}, and \code{"tdist"} are available, with \code{"gaussian"} the default. This argument is tunable. +\item{\code{distribution}}{A string with the distribution used in the loss function of the boosted model. This is supplied to the \code{distribution} argument in \pkgfun{gbm}{gbm.fit}. For binary treatments, \code{"bernoulli"} and \code{"adaboost"} are available, with \code{"bernoulli"} the default. For multi-category treatments, only \code{"multinomial"} is allowed. For continuous treatments \code{"gaussian"}, \code{"laplace"}, and \code{"tdist"} are available, with \code{"gaussian"} the default. This argument is tunable. } -\item{\code{n.trees}}{The maximum number of trees used. This is passed onto the \code{n.trees} argument in \code{gbm.fit()}. The default is 10000 for binary and multinomial treatments and 20000 for continuous treatments. +\item{\code{n.trees}}{The maximum number of trees used. This is passed onto the \code{n.trees} argument in \code{gbm.fit()}. The default is 10000 for binary and multi-category treatments and 20000 for continuous treatments. } \item{\code{start.tree}}{The tree at which to start balance checking. If you know the best balance isn't in the first 100 trees, for example, you can set \code{start.tree = 101} so that balance statistics are not computed on the first 100 trees. This can save some time since balance checking takes up the bulk of the run time for some balance-based stopping methods, and is especially useful when running the same model adding more and more trees. The default is 1, i.e., to start from the very first tree in assessing balance. } -\item{\code{interaction.depth}}{The depth of the trees. This is passed onto the \code{interaction.depth} argument in \code{gbm.fit()}. Higher values indicate better ability to capture nonlinear and nonadditive relationships. The default is 3 for binary and multinomial treatments and 4 for continuous treatments. This argument is tunable. +\item{\code{interaction.depth}}{The depth of the trees. This is passed onto the \code{interaction.depth} argument in \code{gbm.fit()}. Higher values indicate better ability to capture nonlinear and nonadditive relationships. The default is 3 for binary and multi-category treatments and 4 for continuous treatments. This argument is tunable. } -\item{\code{shrinkage}}{The shrinkage parameter applied to the trees. This is passed onto the \code{shrinkage} argument in \code{gbm.fit()}. The default is .01 for binary and multinomial treatments and .0005 for continuous treatments. The lower this value is, the more trees one may have to include to reach the optimum. This argument is tunable. +\item{\code{shrinkage}}{The shrinkage parameter applied to the trees. This is passed onto the \code{shrinkage} argument in \code{gbm.fit()}. The default is .01 for binary and multi-category treatments and .0005 for continuous treatments. The lower this value is, the more trees one may have to include to reach the optimum. This argument is tunable. } \item{\code{bag.fraction}}{The fraction of the units randomly selected to propose the next tree in the expansion. This is passed onto the \code{bag.fraction} argument in \code{gbm.fit()}. The default is 1, but smaller values should be tried. For values less then 1, subsequent runs with the same parameters will yield different results due to random sampling; be sure to seed the seed using \code{\link[=set.seed]{set.seed()}} to ensure replicability of results. } @@ -135,7 +135,7 @@ summary(W1) bal.tab(W1) \dontrun{ - #Balancing covariates with respect to race (multinomial) + #Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "gbm", estimand = "ATT", @@ -196,7 +196,7 @@ bal.tab(W1) McCaffrey, D. F., Ridgeway, G., & Morral, A. R. (2004). Propensity Score Estimation With Boosted Regression for Evaluating Causal Effects in Observational Studies. Psychological Methods, 9(4), 403–425. \doi{10.1037/1082-989X.9.4.403} } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ McCaffrey, D. F., Griffin, B. A., Almirall, D., Slaughter, M. E., Ramchand, R., & Burgette, L. F. (2013). A Tutorial on Propensity Score Estimation for Multiple Treatments Using Generalized Boosted Models. Statistics in Medicine, 32(19), 3388–3414. \doi{10.1002/sim.5753} } diff --git a/man/method_glm.Rd b/man/method_glm.Rd index e2fcd6a..6de044b 100644 --- a/man/method_glm.Rd +++ b/man/method_glm.Rd @@ -5,17 +5,17 @@ \alias{method_ps} \title{Propensity Score Weighting Using Generalized Linear Models} \description{ -This page explains the details of estimating weights from generalized linear model-based propensity scores by setting \code{method = "glm"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. (This method used to be requested with \code{method = "ps"}, and this still works.) +This page explains the details of estimating weights from generalized linear model-based propensity scores by setting \code{method = "glm"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. (This method used to be requested with \code{method = "ps"}, and this still works.) -In general, this method relies on estimating propensity scores with a parametric generalized linear model and then converting those propensity scores into weights using a formula that depends on the desired estimand. For binary and multinomial treatments, a binomial or multinomial regression model is used to estimate the propensity scores as the predicted probability of being in each treatment given the covariates. For ordinal treatments, an ordinal regression model is used to estimate generalized propensity scores. For continuous treatments, a generalized linear model is used to estimate generalized propensity scores as the conditional density of treatment given the covariates. +In general, this method relies on estimating propensity scores with a parametric generalized linear model and then converting those propensity scores into weights using a formula that depends on the desired estimand. For binary and multi-category treatments, a binomial or multinomial regression model is used to estimate the propensity scores as the predicted probability of being in each treatment given the covariates. For ordinal treatments, an ordinal regression model is used to estimate generalized propensity scores. For continuous treatments, a generalized linear model is used to estimate generalized propensity scores as the conditional density of treatment given the covariates. \subsection{Binary Treatments}{ For binary treatments, this method estimates the propensity scores using \code{\link[=glm]{glm()}}. An additional argument is \code{link}, which uses the same options as \code{link} in \code{\link[=family]{family()}}. The default link is "logit", but others, including "probit", are allowed. The following estimands are allowed: ATE, ATT, ATC, ATO, ATM, and ATOS. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ -For multinomial treatments, the propensity scores are estimated using multinomial regression from one of a few functions depending on the requested link: for logit (\code{"logit"}) and probit (\code{"probit"}) links, \pkgfun{mlogit}{mlogit} is used; for the Bayesian probit (\code{"bayes.probit"}) link, \pkgfun{MNP}{mnp} is used; and for the biased-reduced multinomial logistic regression (\code{"br.logit"}), \pkgfun{brglm2}{brmultinom} is used. If the treatment variable is an ordered factor, \pkgfun{MASS}{polr} is used to fit ordinal regression unless \code{link = "br.logit"}, in which case \pkgfun{brglm2}{bracl} is used. Any of the methods allowed in the \code{method} argument of \code{polr()} can be supplied to \code{link}. The following estimands are allowed: ATE, ATT, ATC, ATO, and ATM. The weights for each estimand are computed using the standard formulas or those mentioned above. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. +For multi-category treatments, the propensity scores are estimated using multinomial regression from one of a few functions depending on the requested link: for logit (\code{"logit"}) and probit (\code{"probit"}) links, \pkgfun{mlogit}{mlogit} is used; for the Bayesian probit (\code{"bayes.probit"}) link, \pkgfun{MNP}{mnp} is used; and for the biased-reduced multinomial logistic regression (\code{"br.logit"}), \pkgfun{brglm2}{brmultinom} is used. If the treatment variable is an ordered factor, \pkgfun{MASS}{polr} is used to fit ordinal regression unless \code{link = "br.logit"}, in which case \pkgfun{brglm2}{bracl} is used. Any of the methods allowed in the \code{method} argument of \code{polr()} can be supplied to \code{link}. The following estimands are allowed: ATE, ATT, ATC, ATO, and ATM. The weights for each estimand are computed using the standard formulas or those mentioned above. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. } \subsection{Continuous Treatments}{ @@ -30,7 +30,7 @@ For longitudinal treatments, the weights are the product of the weights estimate \subsection{Sampling Weights}{ -Sampling weights are supported through \code{s.weights} in all scenarios except for multinomial treatments with \code{link = "bayes.probit"} and for binary and continuous treatments with \code{missing = "saem"} (see below). Warning messages may appear otherwise about non-integer successes, and these can be ignored. +Sampling weights are supported through \code{s.weights} in all scenarios except for multi-category treatments with \code{link = "bayes.probit"} and for binary and continuous treatments with \code{missing = "saem"} (see below). Warning messages may appear otherwise about non-integer successes, and these can be ignored. } \subsection{Missing Data}{ @@ -73,7 +73,7 @@ For continuous treatments in the presence of missing data with \code{missing = " \section{Additional Outputs}{ \describe{ -\item{\code{obj}}{When \code{include.obj = TRUE}, the (generalized) propensity score model fit. For binary treatments, the output of the call to \code{\link[=glm]{glm()}}. For ordinal treatments, the output of the call to \pkgfun{MASS}{polr}. For multinomial treatments with \code{link = "logit"} or \code{"probit"} and \code{use.mlogit = TRUE}, the output of the call to \pkgfun{mlogit}{mlogit}. For multinomial treatments with \code{use.mlogit = FALSE}, a list of the \code{glm()} fits. For multinomial treatments with \code{link = "br.logit"}, the output of the call to \pkgfun{brglm2}{brmultinom}. For multinomial treatments with \code{link = "bayes.probit"}, the output of the call to \pkgfun{MNP}{mnp}. For continuous treatments, the output of the call to \code{glm()} for the predicted values in the denominator density. +\item{\code{obj}}{When \code{include.obj = TRUE}, the (generalized) propensity score model fit. For binary treatments, the output of the call to \code{\link[=glm]{glm()}}. For ordinal treatments, the output of the call to \pkgfun{MASS}{polr}. For multi-category treatments with \code{link = "logit"} or \code{"probit"} and \code{use.mlogit = TRUE}, the output of the call to \pkgfun{mlogit}{mlogit}. For multi-category treatments with \code{use.mlogit = FALSE}, a list of the \code{glm()} fits. For multi-category treatments with \code{link = "br.logit"}, the output of the call to \pkgfun{brglm2}{brmultinom}. For multi-category treatments with \code{link = "bayes.probit"}, the output of the call to \pkgfun{MNP}{mnp}. For continuous treatments, the output of the call to \code{glm()} for the predicted values in the denominator density. } } } @@ -90,7 +90,7 @@ data("lalonde", package = "cobalt") summary(W1) bal.tab(W1) -#Balancing covariates with respect to race (multinomial) +#Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "glm", estimand = "ATE", @@ -144,7 +144,7 @@ See references for the \pkg{brglm2} \pkgfun2{brglm2}{brglm2}{package}. Jiang, W., Josse, J., & Lavielle, M. (2019). Logistic regression with missing covariates — Parameter estimation, model selection and prediction within a joint-modeling framework. Computational Statistics & Data Analysis, 106907. \doi{10.1016/j.csda.2019.106907} } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ \itemize{ \item \code{estimand = "ATO"} } diff --git a/man/method_ipt.Rd b/man/method_ipt.Rd new file mode 100644 index 0000000..80b7b06 --- /dev/null +++ b/man/method_ipt.Rd @@ -0,0 +1,115 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/weightit2ipt.R +\name{method_ipt} +\alias{method_ipt} +\title{Inverse Probability Tilting} +\description{ +This page explains the details of estimating weights using inverse probability tilting by setting \code{method = "ipt"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. + +In general, this method relies on estimating propensity scores using a modification of the usual regression score equations to enforce balance and the converting those propensity scores into weights using a formula that depends on the desired estimand. This method relies on code written for \pkg{WeightIt} using \code{\link[=optim]{optim()}}. +\subsection{Binary Treatments}{ + +For binary treatments, this method estimates the weights using \code{optim()} using formulas described by Graham, Pinto, and Egel (2012). The following estimands are allowed: ATE, ATT, and ATC. When the ATE is requested, the optimization is run twice, once for each treatment group, and the return propensity score is the probability of being in the "second" treatment group, i.e., \code{levels(factor(treat))[2]}. +} + +\subsection{Multi-Category Treatments}{ + +For multi-category treatments, this method estimates the weights using \code{optim()}. The following estimands are allowed: ATE and ATT. When the ATE is requested, \code{optim()} is run once for each treatment group. When the ATT is requested, \code{optim()} is run once for each non-focal (i.e., control) group. +} + +\subsection{Continuous Treatments}{ + +For continuous treatments, this method estimates the weights using \code{optim()}. +} + +\subsection{Longitudinal Treatments}{ + +For longitudinal treatments, the weights are the product of the weights estimated at each time point. This method is not guaranteed to yield exact balance at each time point. NOTE: the use of inverse probability tilting with longitudinal treatments has not been validated! +} + +\subsection{Sampling Weights}{ + +Sampling weights are supported through \code{s.weights} in all scenarios. +} + +\subsection{Missing Data}{ + +In the presence of missing data, the following value(s) for \code{missing} are allowed: +\describe{ +\item{\code{"ind"} (default)}{ +First, for each variable with missingness, a new missingness indicator variable is created which takes the value 1 if the original covariate is \code{NA} and 0 otherwise. The missingness indicators are added to the model formula as main effects. The missing values in the covariates are then replaced with the covariate medians (this value is arbitrary and does not affect estimation). The weight estimation then proceeds with this new formula and set of covariates. The covariates output in the resulting \code{weightit} object will be the original covariates with the \code{NA}s. +} +} +} +} +\details{ +Inverse probability tilting (IPT) involves specifying estimating equations that fit the parameters of one or more logistic regression models (for binary and multi-category treatments) or a linear regression model (for continuous treatments) with a modification that ensure exact balance on the covariates means. These estimating equations are solved, and the estimated parameters are used in the (generalized) propensity score, which is used to compute the weights. Conceptually and mathematically, IPT is very similar to entropy balancing and just-identified CBPS. For the ATT and ATC, entropy balancing, just-identified CBPS, and IPT will yield identical results. For the ATE, the three methods differ. + +Treatment effect estimates for binary treatments are consistent if the true propensity score is a logistic regression or the outcome model is linear in the covariates and their interaction with treatments. For entropy balancing, this is only true for the ATT, and fo just-identified CBPS, this is only true if there is no effect modification by covariates. In this way, IPT provides additional theoretical guarantees over the other two methods, though potentially with some cost in precision. + +IPT for continuous treatments has not been described in the literature; here we use the score equations for CBPS with continuous treatments, which correspond to the score equations for the residual variance of a linear regression for the generalized propensity score and the weighted covariance between the treatment and covariates. This method should be used with caution until it is better understood. +} +\section{Additional Arguments}{ + +\code{moments} and \code{int} are accepted. See \code{\link[=weightit]{weightit()}} for details. + +\describe{ +\item{\code{quantile}}{ +A named list of quantiles (values between 0 and 1) for each continuous covariate, which are used to create additional variables that when balanced ensure balance on the corresponding quantile of the variable. For example, setting \verb{quantile = list(x1 = c(.25, .5. , .75))} ensures the 25th, 50th, and 75th percentiles of \code{x1} in each treatment group will be balanced in the weighted sample. Can also be a single number (e.g., \code{.5}) or an unnamed list of length 1 (e.g., \code{list(c(.25, .5, .75))}) to request the same quantile(s) for all continuous covariates, or a named vector (e.g., \verb{c(x1 = .5, x2 = .75}) to request one quantile for each covariate. Only allowed with binary and multi-category treatments. +} +} + +The arguments \code{maxit} and \code{reltol} can be supplied and are passed to the \code{control} argument of \code{\link[=optim]{optim()}}. The \code{"BFGS"} method is used, so the defaults correspond to this. + +The \code{stabilize} argument is ignored. +} + +\section{Additional Outputs}{ + +\describe{ +\item{\code{obj}}{When \code{include.obj = TRUE}, the output of the call to \code{\link[=optim]{optim()}}, which contains the coefficient estimates and convergence information. For ATE fits or with multi-category treatments, a list of \code{optim()} outputs, one for each weighted group. +} +} +} + +\examples{ +data("lalonde", package = "cobalt") + +#Balancing covariates between treatment groups (binary) +(W1 <- weightit(treat ~ age + educ + married + + nodegree + re74, data = lalonde, + method = "ipt", estimand = "ATT")) +summary(W1) +cobalt::bal.tab(W1) + +#Balancing covariates with respect to race (multi-category) +(W2 <- weightit(race ~ age + educ + married + + nodegree + re74, data = lalonde, + method = "ipt", estimand = "ATE")) +summary(W2) +cobalt::bal.tab(W2) + +#Balancing covariates and squares with respect to +#re75 (continuous) +(W3 <- weightit(re75 ~ age + educ + married + + nodegree + re74, data = lalonde, + method = "ipt")) +summary(W3) +cobalt::bal.tab(W3) +} +\references{ +\subsection{ATE}{ + +Graham, B. S., De Xavier Pinto, C. C., & Egel, D. (2012). Inverse Probability Tilting for Moment Condition Models with Missing Data. \emph{The Review of Economic Studies}, 79(3), 1053–1079. \doi{10.1093/restud/rdr047} +} + +\subsection{ATT}{ + +Sant’Anna, P. H. C., & Zhao, J. (2020). Doubly robust difference-in-differences estimators. \emph{Journal of Econometrics}, 219(1), 101–122. \doi{10.1016/j.jeconom.2020.06.003} +} +} +\seealso{ +\code{\link[=weightit]{weightit()}}, \code{\link[=weightitMSM]{weightitMSM()}} + +\link{method_ebal} and \link{method_cbps} for entropy balancing and CBPS, which work similarly. +} diff --git a/man/method_npcbps.Rd b/man/method_npcbps.Rd index 914ac7f..652f0da 100644 --- a/man/method_npcbps.Rd +++ b/man/method_npcbps.Rd @@ -4,7 +4,7 @@ \alias{method_npcbps} \title{Nonparametric Covariate Balancing Propensity Score Weighting} \description{ -This page explains the details of estimating weights from nonparametric covariate balancing propensity scores by setting \code{method = "npcbps"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. +This page explains the details of estimating weights from nonparametric covariate balancing propensity scores by setting \code{method = "npcbps"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. In general, this method relies on estimating weights by maximizing the empirical likelihood of the data subject to balance constraints. This method relies on \pkgfun{CBPS}{npCBPS} from the \CRANpkg{CBPS} package. \subsection{Binary Treatments}{ @@ -12,9 +12,9 @@ In general, this method relies on estimating weights by maximizing the empirical For binary treatments, this method estimates the weights using \pkgfun{CBPS}{npCBPS}. The ATE is the only estimand allowed. The weights are taken from the output of the \code{npCBPS} fit object. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ -For multinomial treatments, this method estimates the weights using \pkgfun{CBPS}{npCBPS}. The ATE is the only estimand allowed. The weights are taken from the output of the \code{npCBPS} fit object. +For multi-category treatments, this method estimates the weights using \pkgfun{CBPS}{npCBPS}. The ATE is the only estimand allowed. The weights are taken from the output of the \code{npCBPS} fit object. } \subsection{Continuous Treatments}{ @@ -83,7 +83,7 @@ data("lalonde", package = "cobalt") summary(W1) bal.tab(W1) - #Balancing covariates with respect to race (multinomial) + #Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "npcbps", estimand = "ATE")) diff --git a/man/method_optweight.Rd b/man/method_optweight.Rd index caea777..c217faf 100644 --- a/man/method_optweight.Rd +++ b/man/method_optweight.Rd @@ -5,7 +5,7 @@ \alias{method_sbw} \title{Optimization-Based Weighting} \description{ -This page explains the details of estimating optimization-based weights (also known as stable balancing weights) by setting \code{method = "optweight"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. +This page explains the details of estimating optimization-based weights (also known as stable balancing weights) by setting \code{method = "optweight"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. In general, this method relies on estimating weights by solving a quadratic programming problem subject to approximate or exact balance constraints. This method relies on \pkgfun{optweight}{optweight} from the \CRANpkg{optweight} package. @@ -15,9 +15,9 @@ Because \code{optweight()} offers finer control and uses the same syntax as \cod For binary treatments, this method estimates the weights using \pkgfun{optweight}{optweight}. The following estimands are allowed: ATE, ATT, and ATC. The weights are taken from the output of the \code{optweight} fit object. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ -For multinomial treatments, this method estimates the weights using \pkgfun{optweight}{optweight}. The following estimands are allowed: ATE and ATT. The weights are taken from the output of the \code{optweight} fit object. +For multi-category treatments, this method estimates the weights using \pkgfun{optweight}{optweight}. The following estimands are allowed: ATE and ATT. The weights are taken from the output of the \code{optweight} fit object. } \subsection{Continuous Treatments}{ @@ -95,7 +95,7 @@ data("lalonde", package = "cobalt") summary(W1) cobalt::bal.tab(W1) -#Balancing covariates with respect to race (multinomial) +#Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "optweight", estimand = "ATE", @@ -119,7 +119,7 @@ Wang, Y., & Zubizarreta, J. R. (2020). Minimal dispersion approximately balancin Zubizarreta, J. R. (2015). Stable Weights that Balance Covariates for Estimation With Incomplete Outcome Data. Journal of the American Statistical Association, 110(511), 910–922. \doi{10.1080/01621459.2015.1023805} } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ de los Angeles Resa, M., & Zubizarreta, J. R. (2020). Direct and stable weight adjustment in non-experimental studies with multivalued treatments: Analysis of the effect of an earthquake on post-traumatic stress. Journal of the Royal Statistical Society: Series A (Statistics in Society), n/a(n/a). \doi{10.1111/rssa.12561} } diff --git a/man/method_super.Rd b/man/method_super.Rd index 1c68e7b..7493396 100644 --- a/man/method_super.Rd +++ b/man/method_super.Rd @@ -4,17 +4,17 @@ \alias{method_super} \title{Propensity Score Weighting Using SuperLearner} \description{ -This page explains the details of estimating weights from SuperLearner-based propensity scores by setting \code{method = "super"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multinomial, and continuous treatments. +This page explains the details of estimating weights from SuperLearner-based propensity scores by setting \code{method = "super"} in the call to \code{\link[=weightit]{weightit()}} or \code{\link[=weightitMSM]{weightitMSM()}}. This method can be used with binary, multi-category, and continuous treatments. -In general, this method relies on estimating propensity scores using the SuperLearner algorithm for stacking predictions and then converting those propensity scores into weights using a formula that depends on the desired estimand. For binary and multinomial treatments, one or more binary classification algorithms are used to estimate the propensity scores as the predicted probability of being in each treatment given the covariates. For continuous treatments, regression algorithms are used to estimate generalized propensity scores as the conditional density of treatment given the covariates. This method relies on \pkgfun{SuperLearner}{SuperLearner} from the \CRANpkg{SuperLearner} package. +In general, this method relies on estimating propensity scores using the SuperLearner algorithm for stacking predictions and then converting those propensity scores into weights using a formula that depends on the desired estimand. For binary and multi-category treatments, one or more binary classification algorithms are used to estimate the propensity scores as the predicted probability of being in each treatment given the covariates. For continuous treatments, regression algorithms are used to estimate generalized propensity scores as the conditional density of treatment given the covariates. This method relies on \pkgfun{SuperLearner}{SuperLearner} from the \CRANpkg{SuperLearner} package. \subsection{Binary Treatments}{ For binary treatments, this method estimates the propensity scores using \pkgfun{SuperLearner}{SuperLearner}. The following estimands are allowed: ATE, ATT, ATC, ATO, ATM, and ATOS. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ -For multinomial treatments, the propensity scores are estimated using several calls to \pkgfun{SuperLearner}{SuperLearner}, one for each treatment group; the treatment probabilities are not normalized to sum to 1. The following estimands are allowed: ATE, ATT, ATC, ATO, and ATM. The weights for each estimand are computed using the standard formulas or those mentioned above. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. +For multi-category treatments, the propensity scores are estimated using several calls to \pkgfun{SuperLearner}{SuperLearner}, one for each treatment group; the treatment probabilities are not normalized to sum to 1. The following estimands are allowed: ATE, ATT, ATC, ATO, and ATM. The weights for each estimand are computed using the standard formulas or those mentioned above. Weights can also be computed using marginal mean weighting through stratification for the ATE, ATT, and ATC. See \code{\link[=get_w_from_ps]{get_w_from_ps()}} for details. } \subsection{Continuous Treatments}{ @@ -78,10 +78,10 @@ For continuous treatments only, the following arguments may be supplied: In addition to the methods allowed by \code{SuperLearner()}, one can specify \code{SL.method = "method.balance"} to use "Balance SuperLearner" as described by Pirracchio and Carone (2018), wherein covariate balance is used to choose the optimal combination of the predictions from the methods specified with \code{SL.library}. Coefficients are chosen (one for each prediction method) so that the weights generated from the weighted combination of the predictions optimize a balance criterion, which must be set with the \code{criterion} argument, described below. \describe{ -\item{\code{criterion}}{A string describing the balance criterion used to select the best weights. See \pkgfun{cobalt}{bal.compute} for allowable options for each treatment type. For binary and multinomial treatments, the default is \code{"smd.mean"}, which minimizes the average absolute standard mean difference among the covariates between treatment groups. For continuous treatments, the default is \code{"p.mean"}, which minimizes the average absolute Pearson correlation between the treatment and covariates. +\item{\code{criterion}}{A string describing the balance criterion used to select the best weights. See \pkgfun{cobalt}{bal.compute} for allowable options for each treatment type. For binary and multi-category treatments, the default is \code{"smd.mean"}, which minimizes the average absolute standard mean difference among the covariates between treatment groups. For continuous treatments, the default is \code{"p.mean"}, which minimizes the average absolute Pearson correlation between the treatment and covariates. } } -Note that this implementation differs from that of Pirracchio and Carone (2018) in that here, balance is measured only on the terms included in the model formula (i.e., and not their interactions unless specifically included), and balance results from a sample weighted using the estimated predicted values as propensity scores, not a sample matched using propensity score matching on the predicted values. Binary and continuous treatments are supported, but currently multinomial treatments are not. +Note that this implementation differs from that of Pirracchio and Carone (2018) in that here, balance is measured only on the terms included in the model formula (i.e., and not their interactions unless specifically included), and balance results from a sample weighted using the estimated predicted values as propensity scores, not a sample matched using propensity score matching on the predicted values. Binary and continuous treatments are supported, but currently multi-category treatments are not. } } @@ -89,7 +89,7 @@ Note that this implementation differs from that of Pirracchio and Carone (2018) \describe{ \item{\code{info}}{ -For binary and continuous treatments, a list with two entries, \code{coef} and \code{cvRisk}. For multinomial treatments, a list of lists with these two entries, one for each treatment level. +For binary and continuous treatments, a list with two entries, \code{coef} and \code{cvRisk}. For multi-category treatments, a list of lists with these two entries, one for each treatment level. \describe{ \item{\code{coef}}{ The coefficients in the linear combination of the predictions from each method in \code{SL.library}. Higher values indicate that the corresponding method plays a larger role in determining the resulting predicted value, and values close to zero indicate that the method plays little role in determining the predicted value. When \code{discrete = TRUE}, these correspond to the coefficients that would have been estimated had \code{discrete} been \code{FALSE}. @@ -100,7 +100,7 @@ The cross-validation risk for each method in \code{SL.library}. Higher values in } } \item{\code{obj}}{ -When \code{include.obj = TRUE}, the SuperLearner fit(s) used to generate the predicted values. For binary and continuous treatments, the output of the call to \pkgfun{SuperLearner}{SuperLearner}. For multinomial treatments, a list of outputs to calls to \code{SuperLearner::SuperLearner()}. +When \code{include.obj = TRUE}, the SuperLearner fit(s) used to generate the predicted values. For binary and continuous treatments, the output of the call to \pkgfun{SuperLearner}{SuperLearner}. For multi-category treatments, a list of outputs to calls to \code{SuperLearner::SuperLearner()}. } } } @@ -119,7 +119,7 @@ data("lalonde", package = "cobalt") summary(W1) bal.tab(W1) \donttest{ - #Balancing covariates with respect to race (multinomial) + #Balancing covariates with respect to race (multi-category) (W2 <- weightit(race ~ age + educ + married + nodegree + re74, data = lalonde, method = "super", estimand = "ATE", @@ -158,7 +158,7 @@ bal.tab(W4, stats = c("m", "ks")) Pirracchio, R., Petersen, M. L., & van der Laan, M. (2015). Improving Propensity Score Estimators’ Robustness to Model Misspecification Using Super Learner. American Journal of Epidemiology, 181(2), 108–119. \doi{10.1093/aje/kwu253} } -\subsection{Multinomial Treatments}{ +\subsection{Multi-Category Treatments}{ Imai, K., & Ratkovic, M. (2014). Covariate balancing propensity score. Journal of the Royal Statistical Society: Series B (Statistical Methodology), 76(1), 243–263. } diff --git a/man/sbps.Rd b/man/sbps.Rd index 5748a93..0633b31 100644 --- a/man/sbps.Rd +++ b/man/sbps.Rd @@ -80,7 +80,7 @@ estimated in the subgroup. There are 2^R permutations of overall and subgroup weights, where R is the number of subgroups. The optimal permutation is chosen as that which minimizes a balance criterion as described in DZZL. The balance criterion used here is, for binary and -multinomial treatments, the sum of the squared standardized mean differences +multi-category treatments, the sum of the squared standardized mean differences within subgroups and overall, which are computed using \code{\link[cobalt:balance-summary]{cobalt::col_w_smd()}}, and for continuous treatments, the sum of the squared correlations between each covariate and treatment within diff --git a/man/weightit.Rd b/man/weightit.Rd index 5a8b3b6..b054a9f 100644 --- a/man/weightit.Rd +++ b/man/weightit.Rd @@ -57,8 +57,7 @@ the focal group. If specified, \code{estimand} will automatically be set to \item{by}{a string containing the name of the variable in \code{data} for which weighting is to be done within categories or a one-sided formula with -the stratifying variable on the right-hand side. For example, if \code{by = "gender"} or \code{by = ~gender}, weights will be generated separately -within each level of the variable \code{"gender"}. (The argument used to be +the stratifying variable on the right-hand side. For example, if \code{by = "gender"} or \code{by = ~gender}, a separate propensity score model or optimization will occur within each level of the variable \code{"gender"}. (The argument used to be called \code{exact}, which will still work but with a message.) Only one \code{by} variable is allowed; to stratify by multiply variables simultaneously, create a new variable that is a full cross of those @@ -129,7 +128,7 @@ the fitting process.} \item{estimand}{The estimand requested.} \item{method}{The weight estimation method specified.} \item{ps}{The estimated or provided propensity scores. Estimated propensity scores are -returned for binary treatments and only when \code{method} is \code{"glm"}, \code{"gbm"}, \code{"cbps"}, \code{"super"}, or \code{"bart"}.} +returned for binary treatments and only when \code{method} is \code{"glm"}, \code{"gbm"}, \code{"cbps"}, \code{"ipt"}, \code{"super"}, or \code{"bart"}.} \item{s.weights}{The provided sampling weights.} \item{focal}{The focal treatment level if the ATT or ATC was requested.} \item{by}{A data.frame containing the \code{by} variable when specified.} @@ -156,6 +155,7 @@ which estimands are allowed, and whether sampling weights are allowed.\tabular{l \code{\link[=method_cbps]{"cbps"}} \tab Covariate Balancing Propensity Score weighting \cr \code{\link[=method_npcbps]{"npcbps"}} \tab Non-parametric Covariate Balancing Propensity Score weighting \cr \code{\link[=method_ebal]{"ebal"}} \tab Entropy balancing \cr + \code{\link[=method_ipt]{"ipt"}} \tab Inverse probability tilting \cr \code{\link[=method_optweight]{"optweight"}} \tab Optimization-based weighting \cr \code{\link[=method_super]{"super"}} \tab Propensity score weighting using SuperLearner \cr \code{\link[=method_bart]{"bart"}} \tab Propensity score weighting using Bayesian additive regression trees (BART) \cr diff --git a/man/weightitMSM.Rd b/man/weightitMSM.Rd index 418c6af..14a823d 100644 --- a/man/weightitMSM.Rd +++ b/man/weightitMSM.Rd @@ -44,7 +44,7 @@ Stabilizing the weights involves fitting a model predicting treatment at each time point from treatment status at prior time points. If \code{TRUE}, a fully saturated model will be fit (i.e., all interactions between all treatments up to each time point), essentially using the observed treatment -probabilities in the numerator (for binary and multinomial treatments). This +probabilities in the numerator (for binary and multi-category treatments). This may yield an error if some combinations are not observed. Default is \code{FALSE}. To manually specify stabilization model formulas, e.g., to specify non-saturated models, use \code{num.formula}. With many time points, @@ -122,7 +122,7 @@ A \code{weightitMSM} object with the following elements: \item{treat.list}{A list of the values of the time-varying treatment variables.} \item{covs.list}{A list of the covariates used in the fitting at each time point. Only includes the raw covariates, which may have been altered in the fitting process.} \item{data}{The data.frame originally entered to \code{weightitMSM()}.} -\item{estimand}{"ATE", currently the only estimand for MSMs with binary or multinomial treatments.} +\item{estimand}{"ATE", currently the only estimand for MSMs with binary or multi-category treatments.} \item{method}{The weight estimation method specified.} \item{ps.list}{A list of the estimated propensity scores (if any) at each time point.} \item{s.weights}{The provided sampling weights.} @@ -132,7 +132,7 @@ A \code{weightitMSM} object with the following elements: \description{ \code{weightitMSM()} allows for the easy generation of balancing weights for marginal structural models for time-varying treatments using a variety of -available methods for binary, continuous, and multinomial treatments. Many +available methods for binary, continuous, and multi-category treatments. Many of these methods exist in other packages, which \code{\link[=weightit]{weightit()}} calls; these packages must be installed to use the desired method. } diff --git a/vignettes/estimating-effects.Rmd b/vignettes/estimating-effects.Rmd index 1170e0e..d04a0fc 100644 --- a/vignettes/estimating-effects.Rmd +++ b/vignettes/estimating-effects.Rmd @@ -145,7 +145,7 @@ There are other methods to incorporate the outcome model into estimation of the ### Modeling the Outcome -The goal of the outcome model is to generate good predictions for use in the g-computation procedure described above. The type and form of the outcome model should depend on the outcome type. For continuous outcomes, one can use a linear model regressing the outcome on the treatment; for binary outcomes, one can use a generalized linear model with, e.g., a logistic link; for time-to-event outcomes, one can use a Cox proportional hazards model. Note that the purpose of including the outcome model is not arrive at a doubly robust estimator (i.e., one that is consistent if either the outcome or propensity score model is correct); rather, it is simply to increase the precision of the weighted estimate essentially for free. To take advantage of this feature, it is important to use a canonical link (i.e., the default link for a given family), as recommended by @gabrielInverseProbabilityTreatment2023. +The goal of the outcome model is to generate good predictions for use in the g-computation procedure described above. The type and form of the outcome model should depend on the outcome type. For continuous outcomes, one can use a linear model regressing the outcome on the treatment; for binary outcomes, one can use a generalized linear model with, e.g., a logistic link; for time-to-event outcomes, one can use a Cox proportional hazards model. Note that the purpose of including the outcome model is not to arrive at a doubly robust estimator (i.e., one that is consistent if either the outcome or propensity score model is correct); rather, it is simply to increase the precision of the weighted estimate essentially for free. To take advantage of this feature, it is important to use a canonical link (i.e., the default link for a given family), as recommended by @gabrielInverseProbabilityTreatment2023. An additional decision to make is whether (and how) to include covariates in the outcome model. One may ask, why use weighting at all if you are going to model the outcome with covariates anyway? Weighting reduces the dependence of the effect estimate on correct specification of the outcome model; this is the central thesis of @hoMatchingNonparametricPreprocessing2007 (though applied to matching in their case). Including covariates in the outcome model after weighting has several functions: it can increase precision in the effect estimate, reduce the bias due to residual imbalance, and make the effect estimate "doubly robust", which means it is consistent if either the weighting reduces sufficient imbalance in the covariates or if the outcome model is correct. For these reasons, we recommend covariate adjustment after weighting when possible. There is some evidence that covariate adjustment is most helpful for covariates with standardized mean differences greater than .1 [@nguyenDoubleadjustmentPropensityScore2017], so these covariates and covariates thought to be highly predictive of the outcome should be prioritized in treatment effect models if not all can be included due to sample size constraints.