bw_sbw() specifies stable balancing weights for balance(). Among all
weightings that hold each reweighted exposure group's covariate means inside a
tolerance band, stable balancing weights select the one of least dispersion,
following Zubizarreta. The default "l2" norm minimizes the sum of squared
weights, so for a fixed per-group total it minimizes the weight variance.
Stable balancing weights support binary, categorical, and continuous
exposures.
Usage
bw_sbw(
...,
norm = c("l2", "l1", "linf"),
min_weight = 1e-08,
convergence_tolerance = NULL,
max_iterations = NULL
)Arguments
- ...
Reserved for future extensions; must be empty. Tuning parameters must be passed by name.
- norm
The weight-dispersion norm to minimize, one of
"l2"(the sum of squared weights, minimum variance),"l1"(the sum of absolute deviations from one), or"linf"(the largest absolute deviation from one).- min_weight
The smallest permitted weight.
- convergence_tolerance
The quadratic-program solver tolerance, or
NULLfor the core default.- max_iterations
The maximum solver iterations, or
NULLfor the core default.
Value
An bw_sbw specification, a balance_method.
Details
The balance tolerance is the method's central tuning parameter. It is set
through constraints = balance_terms(tolerance = ...) in balance(), not on
the method spec, and it must be positive: with an exact (zero) tolerance the
problem reduces to exact moment balance, which abandons the minimum-variance
rationale and is prone to infeasibility, so a fit without a positive tolerance
is refused. Given a positive tolerance the weights hold each group's weighted
covariate means within the band while minimizing the weight dispersion. For a
discrete exposure no feasible reweighting has smaller dispersion than the fit
returns.
A single scalar tolerance applies to every covariate; a named vector sets a tolerance per covariate. A covariate left at zero in a named vector demands exact balance on that covariate while the others are relaxed, the infeasibility-prone case, so a mixed specification is an explicit choice rather than a convenience.
For a discrete exposure the constraints default to first-moment balance; pass
balance_terms() to balance higher moments, interactions, or quantiles, each
inside its tolerance band. For a focal estimand the focal group keeps unit
weight and the other groups are pulled to the focal group's covariate means.
For a continuous exposure the weighted exposure-covariate correlations are held within the tolerance. The quadratic program bounds a linearized correlation whose scales are fixed at the sample, so the fit tightens that internal bound over a few passes until the reported weighted correlation sits inside the requested band. The returned weights therefore minimize dispersion over the tightened internal band rather than over every weighting that meets the reported band, so the strict minimum-dispersion guarantee is stated for discrete exposures only.
Stable balancing weights belong to the quadratic-program family, which has no estimating equations, so a fit produces no estimating-equations container.
The norm argument selects how the weight dispersion is measured, always
against the uniform baseline of one within each reweighted group. "l2"
minimizes the sum of squared weights, so for a fixed per-group total it
minimizes the weight variance. "l1" minimizes the sum of absolute deviations
from one, which tends to leave many weights untouched and concentrate the
reweighting on a few units. "linf" minimizes the single largest absolute
deviation from one, which spreads the reweighting as evenly as the balance
constraints allow. The "l1" and "linf" problems are linear programs solved
through the same quadratic-program backends as "l2"; their solutions can be
non-unique, so a fit reports the achieved dispersion rather than promising a
unique weighting.
References
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.
Examples
n <- 200
x1 <- rnorm(n)
x2 <- rnorm(n)
df <- data.frame(
exposure = rbinom(n, 1, plogis(0.5 * x1 - 0.5 * x2)),
x1 = x1,
x2 = x2
)
fit <- balance(
df,
exposure,
c(x1, x2),
method = bw_sbw(),
constraints = balance_terms(tolerance = 0.05)
)
#> ℹ Treating `.exposure` as binary
fit
#>
#> ── Stable balancing weights ────────────────────────────────────────────────────
#> Exposure: "exposure" (binary)
#> Estimand: "ate"
#> Observations: 200
#> Solver: converged in 75 iterations
#> Constraints: 2 terms (tolerance 0.05)
#> Largest imbalance: 0.1000 (standardized mean difference)