Tidy per-shift LMTP positivity summary (IPSI-friendly)
Source:R/margot_ipsi_summary.R
margot_ipsi_summary.RdBuilds 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")
} # }