Skip to contents

Builds a single, tidy table per shift with practical-positivity diagnostics and optional effect columns (ATT, CI, E-value) when supplied. Designed to compare incremental propensity score interventions (IPSI) such as `ipsi_02`, `ipsi_05`, `ipsi_10` without refitting, but works for any set of shifts available in an LMTP run object.

Usage

margot_ipsi_summary(
  x,
  outcome,
  shifts = NULL,
  waves = NULL,
  test_thresholds = list(prod_log10 = -1, prod_frac_warn = 0.1, near_zero_median = 0.001,
    near_zero_cv = 0.05),
  include_policy_rates = TRUE,
  effect_table = NULL,
  digits = 3,
  compact = TRUE,
  include_explanation = TRUE
)

Arguments

x

Result of `margot_lmtp()` (list with `$models`) or a list of models each exposing `$density_ratios` (matrix with waves in columns). Optionally models may include `$exposure_by_wave` to enable policy-rate summaries.

outcome

Character outcome name (must exist under `x$models`).

shifts

Character vector of shifts to include (full names or cleaned suffixes). If NULL, includes all available for the outcome.

waves

Optional integer vector of waves to include; defaults to all.

test_thresholds

Named list controlling tests. Recognised names: - `prod_log10` (default -1) threshold on log10(product of ratios) for uncensored rows. - `prod_frac_warn` (default 0.10) warning fraction; verdict is Pass when fraction ≤ this. - `near_zero_median` (default 1e-3) and `near_zero_cv` (default 0.05) are computed but not included in the verdict; they are returned as counts of flagged waves per shift.

include_policy_rates

Logical; if TRUE and exposure-by-wave aligned with density ratios is available, returns policy-implied Pr(A_t=1) by wave (uncensored rows).

effect_table

Optional data.frame with effect columns to merge by (outcome, shift). Expected columns (case-insensitive, flexible names): `outcome`, `shift` (either full or cleaned), and any of `att`, `ci_low`, `ci_high`, `e_value`, `e_value_bound`.

digits

Integer; rounding for numeric outputs.

Value

A tibble/data.frame with one row per shift containing: `outcome`, `shift_full`, `shift_clean`, optional `delta` (parsed from IPSI names), product-of-r metrics, verdict, ESS metrics, optional policy rates (per-wave `p_hat_wave_k` and `p_hat_overall`), optional effect columns if provided.

Details

Metrics include: - Product-of-r collapse across selected waves (uncensored fraction below a user threshold on log10 scale, with Pass/Fail verdict), and percent collapsing to zero including censoring (IPCW zeros). - ESS on uncensored rows overall and relative to person-time (ESS+/(N_pt)). - Policy-implied exposure rates by wave (and overall) on uncensored rows when `exposure_by_wave` is attached to models (best-effort from `margot_lmtp()`). - Optional effect columns merged from a user-supplied `effect_table`.

Examples

if (FALSE) { # \dontrun{
# Given an LMTP run with IPSI shifts
tbl <- margot_ipsi_summary(
  x = fit_ipsi,
  outcome = "t5_meaning_purpose_z",
  shifts = c("null", "ipsi_02", "ipsi_05", "ipsi_10"),
  test_thresholds = list(prod_log10 = -1, prod_frac_warn = 0.10),
  include_policy_rates = TRUE,
  digits = 3
)

# Compact table for reporting (kable-friendly headers)
tbl_compact <- margot_ipsi_summary(
  x = fit_ipsi,
  outcome = "t5_meaning_purpose_z",
  shifts = c("null", "ipsi_02", "ipsi_05", "ipsi_10"),
  test_thresholds = list(prod_log10 = -1, prod_frac_warn = 0.10),
  include_policy_rates = FALSE,
  digits = 3,
  compact = TRUE,
  include_explanation = TRUE
)
if (requireNamespace("knitr", quietly = TRUE)) {
  knitr::kable(tbl_compact, format = "markdown")
}
# Print non-specialist explanation
cat(attr(tbl_compact, "explanation"), "\n")
} # }