Skip to contents

Builds one row per covariate \(\times\) analysis scale containing the observed ESS/WESS, a bootstrap confidence interval (model sampling variability), and a chance interval (null distribution from group-label permutation). The resulting table answers whether each covariate's model confidence interval clears the chance interval.

Usage

oda_balance_effect_table(
  group,
  X,
  w = NULL,
  compare_weights = FALSE,
  covariate_types = NULL,
  nboot = 2000L,
  chance_iter = 2000L,
  ci = 0.95,
  mc_seed = NULL,
  mc_iter = 1000L,
  ...
)

Arguments

group

Integer (or coercible) binary group indicator with exactly two distinct non-missing values. Plays y in ODA.

X

Data frame of baseline covariate columns (nrow(X) == length(group)).

w

Optional numeric case-weight vector. When supplied, weighted ODA is used and metric = "WESS".

compare_weights

Logical; when TRUE and w is supplied, produces two rows per covariate: analysis = "unweighted" (w ignored) and analysis = "weighted" (w used). Default FALSE.

covariate_types

Optional named character vector mapping column names to ODA attribute types. Unmapped columns use "auto".

nboot

Integer; number of bootstrap resamples. Default 2000L.

chance_iter

Integer; number of group-label permutations for the null interval. Default 2000L.

ci

Numeric; nominal coverage for both intervals. Default 0.95.

mc_seed

Integer RNG seed set once at function entry. Controls all bootstrap and permutation sampling deterministically. NULL for unseeded.

mc_iter

Integer; MC iterations passed to the observed oda_fit call. Default 1000L.

...

Additional arguments forwarded to each oda_fit call (e.g., priors_on, loo). mcarlo and mc_iter are controlled internally and must not be passed here.

Value

A list of class "oda_balance_effect_table" with:

rows

Data frame; one row per covariate \(\times\) analysis scale. Columns: attribute, analysis, metric, estimate, boot_lo, boot_hi, chance_lo, chance_hi, p_mc, p_sidak, p_bonferroni, rule_summary, sensitivity, specificity, n_total, balanced_by_interval, residual_imbalance.

meta

List of metadata: n_covariates, n_obs, has_weights, compare_weights, analyses, nboot, chance_iter, ci, mc_iter, mc_seed.

Details

Three passes are run per covariate:

  1. Observed: oda_fit(mcarlo = TRUE) – point estimate and Monte Carlo p-value.

  2. Bootstrap: nboot resamples (rows with replacement), mcarlo = FALSE – percentile confidence interval.

  3. Chance: chance_iter group-label permutations, mcarlo = FALSE – null percentile interval.

When compare_weights = TRUE and w is supplied, both an "unweighted" and a "weighted" row are produced per covariate. Multiplicity corrections (Sidak, Bonferroni) are applied within each analysis scale across covariates.

Interpretation:

  • balanced_by_interval = TRUE: model bootstrap CI overlaps the chance interval (boot_lo <= chance_hi) – no evidence of residual imbalance for this covariate.

  • residual_imbalance = TRUE: model CI clears chance (boot_lo > chance_hi) – residual imbalance detected.

References

Linden A, Yarnold PR (2016). Using machine learning to assess covariate balance in matching studies. Journal of Evaluation in Clinical Practice, 22(6), 861-867.

Examples

set.seed(1)
group <- c(rep(0L, 30), rep(1L, 30))
X <- data.frame(
  age   = c(rnorm(30, 45, 8), rnorm(30, 55, 8)),
  score = rnorm(60, 50, 10)
)
et <- oda_balance_effect_table(group, X,
                                nboot = 50L, chance_iter = 50L,
                                mc_iter = 200L, mc_seed = 1L)
et$rows[, c("attribute", "estimate", "boot_lo", "boot_hi",
            "chance_lo", "chance_hi", "balanced_by_interval")]
#>   attribute estimate  boot_lo  boot_hi chance_lo chance_hi balanced_by_interval
#> 1       age 63.33333 51.08438 79.78837     10.00  33.33333                FALSE
#> 2     score 20.00000 14.52020 40.90137     10.75  36.66667                 TRUE