| wt_ate | R Documentation |
Compute inverse probability weights for causal inference under different estimands. Each function targets a different population:
wt_ate(): Average Treatment Effect – the full population.
wt_att(): Average Treatment Effect on the Treated – the treated
(focal) group.
wt_atu(): Average Treatment Effect on the Untreated – the
untreated (reference) group. wt_atc() is an alias.
wt_atm(): Average Treatment Effect for the Evenly Matchable –
units with the most overlap.
wt_ato(): Average Treatment Effect for the Overlap Population –
weights proportional to overlap.
wt_entropy(): Entropy-weighted Average Treatment Effect –
an entropy-balanced population.
wt_cens(): Inverse probability of censoring weights – uses the
same formula as wt_ate() but labels the estimand "uncensored". Use
these to adjust for censoring in survival analysis, not for treatment
weighting.
.propensity accepts a numeric vector of predicted probabilities, a
data.frame of per-level probabilities, a fitted glm object, or a
modified propensity score created by ps_trim(), ps_trunc(),
ps_refit(), or ps_calibrate().
All functions return a psw object – a numeric vector that tracks the
estimand, stabilization status, and any trimming or truncation applied.
wt_ate(
.propensity,
.exposure,
.sigma = NULL,
exposure_type = c("auto", "binary", "categorical", "continuous"),
.focal_level = NULL,
.reference_level = NULL,
stabilize = FALSE,
stabilization_score = NULL,
...,
.treated = NULL,
.untreated = NULL
)
## S3 method for class 'data.frame'
wt_ate(
.propensity,
.exposure,
.sigma = NULL,
exposure_type = c("auto", "binary", "categorical", "continuous"),
.focal_level = NULL,
.reference_level = NULL,
stabilize = FALSE,
stabilization_score = NULL,
...,
.propensity_col = NULL,
.treated = NULL,
.untreated = NULL
)
wt_att(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.treated = NULL,
.untreated = NULL
)
## S3 method for class 'data.frame'
wt_att(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.propensity_col = NULL,
.treated = NULL,
.untreated = NULL
)
wt_atu(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.treated = NULL,
.untreated = NULL
)
## S3 method for class 'data.frame'
wt_atu(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.propensity_col = NULL,
.treated = NULL,
.untreated = NULL
)
wt_atm(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.treated = NULL,
.untreated = NULL
)
## S3 method for class 'data.frame'
wt_atm(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.propensity_col = NULL,
.treated = NULL,
.untreated = NULL
)
wt_ato(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.treated = NULL,
.untreated = NULL
)
## S3 method for class 'data.frame'
wt_ato(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.propensity_col = NULL,
.treated = NULL,
.untreated = NULL
)
wt_entropy(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.treated = NULL,
.untreated = NULL
)
## S3 method for class 'data.frame'
wt_entropy(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.propensity_col = NULL,
.treated = NULL,
.untreated = NULL
)
wt_atc(
.propensity,
.exposure,
exposure_type = c("auto", "binary", "categorical"),
.focal_level = NULL,
.reference_level = NULL,
...,
.treated = NULL,
.untreated = NULL
)
wt_cens(
.propensity,
.exposure,
.sigma = NULL,
exposure_type = c("auto", "binary", "categorical", "continuous"),
.focal_level = NULL,
.reference_level = NULL,
stabilize = FALSE,
stabilization_score = NULL,
...,
.treated = NULL,
.untreated = NULL
)
## S3 method for class 'data.frame'
wt_cens(
.propensity,
.exposure,
.sigma = NULL,
exposure_type = c("auto", "binary", "categorical", "continuous"),
.focal_level = NULL,
.reference_level = NULL,
stabilize = FALSE,
stabilization_score = NULL,
...,
.propensity_col = NULL,
.treated = NULL,
.untreated = NULL
)
.propensity |
Propensity scores in one of several forms:
|
.exposure |
The exposure (treatment) variable. For binary exposures, a
numeric 0/1 vector, logical, or two-level factor. For categorical
exposures, a factor or character vector. For continuous exposures, a
numeric vector. Optional when |
.sigma |
Numeric vector of observation-level standard deviations for
continuous exposures (e.g., |
exposure_type |
Type of exposure: |
.focal_level |
The value of |
.reference_level |
The value of |
stabilize |
If |
stabilization_score |
Optional numeric value to use as the
stabilization multiplier instead of the default (the marginal mean of
|
... |
These dots are for future extensions and must be empty. |
.treated |
|
.untreated |
|
.propensity_col |
Column to use when |
All weight functions support binary exposures. wt_ate() and wt_cens()
also support continuous exposures. All except wt_cens() support
categorical exposures.
Binary: .exposure is a two-level vector (e.g., 0/1, logical, or a
two-level factor). .propensity is a numeric vector of P(treatment | X).
Categorical: .exposure is a factor or character vector with 3+
levels. .propensity must be a matrix or data frame with one column per
level, where rows sum to 1.
Continuous: .exposure is a numeric vector. .propensity is a
vector of conditional means (fitted values). Weights use a normal density
ratio; stabilization is strongly recommended.
Auto (default): Detects the exposure type from .exposure.
Setting stabilize = TRUE multiplies the base weight by an estimate of
P(A) (binary) or f_A(A) (continuous), reducing variance. When no
stabilization_score is supplied, the marginal mean of .exposure is
used. Stabilization is supported for ATE and censoring weights
(wt_ate() and wt_cens()) and is strongly recommended for continuous
exposures.
Extreme weights signal positivity violations, poor model fit, or limited overlap. You can address them by:
Choosing an overlap-focused estimand (wt_ato(), wt_atm(),
wt_entropy()), which down-weight units in regions of poor overlap.
Trimming (ps_trim()) or truncating (ps_trunc()) propensity scores
before computing weights.
Calibrating weights with ps_calibrate().
Stabilizing ATE weights (stabilize = TRUE).
See the halfmoon package for weight diagnostics and visualization.
For binary treatments (A \in \{0, 1\}), with propensity score
e(X) = P(A=1 \mid X):
ATE: w = \frac{A}{e(X)} + \frac{1-A}{1-e(X)}
ATT: w = A + \frac{(1-A) \cdot e(X)}{1-e(X)}
ATU: w = \frac{A \cdot (1-e(X))}{e(X)} + (1-A)
ATM: w = \frac{\min(e(X), 1-e(X))}{A \cdot e(X) + (1-A) \cdot (1-e(X))}
ATO: w = A \cdot (1-e(X)) + (1-A) \cdot e(X)
Entropy: w = \frac{h(e(X))}{A \cdot e(X) + (1-A) \cdot (1-e(X))}, where h(e) = -[e \log(e) + (1-e) \log(1-e)]
Weights use the density ratio
w = f_A(A) / f_{A|X}(A \mid X), where f_A is the marginal
density and f_{A|X} is the conditional density (both assumed
normal). Only wt_ate() and wt_cens() support continuous exposures.
For K-level treatments, weights take the tilting-function form
w_i = h(\mathbf{e}_i) / e_{i,Z_i}, where e_{i,Z_i} is the
propensity for unit i's observed level and h(\cdot) depends
on the estimand:
ATE: h(\mathbf{e}) = 1
ATT: h(\mathbf{e}) = e_{\text{focal}}
ATU: h(\mathbf{e}) = 1 - e_{\text{focal}}
ATM: h(\mathbf{e}) = \min(e_1, \ldots, e_K)
ATO: h(\mathbf{e}) = \bigl(\sum_k 1/e_k\bigr)^{-1}
Entropy: h(\mathbf{e}) = -\sum_k e_k \log(e_k)
A psw vector (a double vector with class psw) carrying
these attributes:
estimand: character, e.g. "ate", "att", "uncensored".
stabilized: logical, whether stabilization was applied.
trimmed: logical, whether the propensity scores were trimmed.
truncated: logical, whether the propensity scores were truncated.
calibrated: logical, whether the propensity scores were calibrated.
Barrett, M., D'Agostino McGowan, L., & Gerke, T. Causal Inference in R. https://www.r-causal.org/
Rosenbaum, P. R., & Rubin, D. B. (1983). The central role of the propensity score in observational studies for causal effects. Biometrika, 70(1), 41–55.
Li, L., & Greene, T. (2013). A weighting analogue to pair matching in propensity score analysis. The International Journal of Biostatistics, 9(2), 215–234. (ATM weights)
Li, F., Morgan, K. L., & Zaslavsky, A. M. (2018). Balancing covariates via propensity score weighting. Journal of the American Statistical Association, 113(521), 390–400. (ATO weights)
Zhou, Y., Matsouaka, R. A., & Thomas, L. (2020). Propensity score weighting under limited overlap and model misspecification. Statistical Methods in Medical Research, 29(12), 3721–3756. (Entropy weights)
Hirano, K., & Imbens, G. W. (2004). The propensity score with continuous treatments. In Applied Bayesian Modeling and Causal Inference from Incomplete-Data Perspectives (pp. 73–84).
Austin, P. C., & Stuart, E. A. (2015). Moving towards best practice when using inverse probability of treatment weighting (IPTW). Statistics in Medicine, 34(28), 3661–3679.
psw() for the returned weight vector class.
ps_trim(), ps_trunc(), ps_refit(), and ps_calibrate() for
modifying propensity scores before weighting.
ipw() for inverse-probability-weighted estimation of causal effects.
# -- Binary exposure, numeric propensity scores ----------------------
set.seed(123)
ps <- runif(100, 0.1, 0.9)
trt <- rbinom(100, 1, ps)
wt_ate(ps, trt)
wt_att(ps, trt)
wt_atu(ps, trt)
wt_atm(ps, trt)
wt_ato(ps, trt)
wt_entropy(ps, trt)
# Stabilized ATE weights (reduces variance)
wt_ate(ps, trt, stabilize = TRUE)
# Inspect the result
w <- wt_ate(ps, trt)
estimand(w)
summary(w)
# -- Overlap-focused estimands handle extreme PS better --------------
ps_extreme <- c(0.01, 0.02, 0.98, 0.99, rep(0.5, 4))
trt_extreme <- c(0, 0, 1, 1, 0, 1, 0, 1)
max(wt_ate(ps_extreme, trt_extreme))
max(wt_ato(ps_extreme, trt_extreme))
# -- From a fitted GLM -----------------------------------------------
x1 <- rnorm(100)
x2 <- rnorm(100)
trt2 <- rbinom(100, 1, plogis(0.5 * x1 + 0.3 * x2))
ps_model <- glm(trt2 ~ x1 + x2, family = binomial)
# Exposure is extracted from the model automatically
wt_ate(ps_model)
# -- Data frame input ------------------------------------------------
ps_df <- data.frame(
control = c(0.9, 0.7, 0.3, 0.1),
treated = c(0.1, 0.3, 0.7, 0.9)
)
exposure <- c(0, 0, 1, 1)
wt_ate(ps_df, exposure)
wt_ate(ps_df, exposure, .propensity_col = "treated")
# -- Censoring weights -----------------------------------------------
cens_ps <- runif(50, 0.6, 0.95)
cens_ind <- rbinom(50, 1, cens_ps)
wt_cens(cens_ps, cens_ind)
estimand(wt_cens(cens_ps, cens_ind)) # "uncensored"
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.