Propensity Score

Analyze → Propensity Score. For observational data, where treatment was not randomized: the treated and untreated groups differ in ways that also drive the outcome, so comparing them directly confounds the treatment's effect with who happened to receive it. The propensity score is each case's probability of treatment given its covariates; matching or weighting on it builds a comparison where the groups look alike on those covariates — closer to what a randomized design would have produced.

The workflow is three steps in one procedure: estimate the score, adjust (match or weight), and check balance. The adjusted sample is then handed back to you as an ordinary variable, so any analysis in the application can run on it.

The data layout

  • Treatment — a numeric variable coded 0/1, with 1 = treated. Any other value stops the analysis with a message (recode first if your groups are labelled differently).
  • Covariates — numeric pre-treatment characteristics that may drive both treatment and outcome. Choose them for what they are, not for significance: the score model is a means to balance, not a model to interpret.

Weighting. The Weight Cases setting does not apply here — pairing weighted cases is not well defined, and layering the IPTW weight this procedure produces on top of another weight would compound two case multiplicities. An active weight variable only selects cases, and the output says so.

The dialog

Pick the Treatment and tick the Covariates. Then choose the Method:

  • Match nearest controls (ATT) — each treated case takes its nearest control(s) by propensity score, greedily, without replacement (a control is used once), hardest-to-match first. The estimand is the average effect on the treated: the matched sample resembles the treated group by construction.
    • Controls per treated (k) — 1:k matching (default 1). A treated case keeps a partial set if the control pool runs out.
    • Caliper — the widest acceptable match distance, in standard deviations of the logit of the score (0.2 is the common recommendation). A treated case with no control inside the caliper is left unmatched and counted in the summary — better an honest smaller sample than a forced bad pair. Blank means no caliper.
  • Weight by inverse probability (IPTW) — every case is kept and weighted: under the default ATE estimand, treated cases by 1/e and controls by 1/(1−e), where e is the score; under ATT, treated cases keep weight 1 and controls get e/(1−e). Check the summary's maximum weight: a huge weight means one case with a score near 0 or 1 dominates the weighted sample.

Save options: the matched-sample filter (propensity_matched, a 1/0 variable — on by default for matching), the IPTW weight (propensity_weight — on by default for weighting), and optionally the score itself (propensity_score).

Reading the output

  • Propensity Score Model — the logistic model behind the score (coefficients, Wald tests, odds ratios). It is diagnostics, not findings: a "significant" covariate here is not a treatment effect.
  • Propensity Match Summary / Propensity Weight Summary — how many cases matched (and how many treated found no in-caliper control), or the weight distribution per group.
  • Propensity Balance — the point of the exercise: each covariate's standardized mean difference (treated − control, over the unadjusted pooled SD) before and after adjustment, on one shared scale. |SMD| ≤ 0.1 is the common adequate-balance benchmark. A covariate still imbalanced after adjustment is a warning to revisit the score model (interactions, transformations) — not to proceed regardless.
  • Balance Plot (the Plot balance (before vs after) checkbox, on by default) — the same numbers as paired points per covariate, with zero (perfect balance) always in view. Before → After collapsing toward the zero line is the picture of a successful adjustment. It exports like any other chart — PNG, or SVG/PDF since 0.22.0 (Exporting one chart); as a chart attached to an analysis it takes no Edit chart… button.

Every table and the plot carry an Ask the assistant about this action (0.22.0), which hands the rendered result to the AI assistant to interpret rather than re-run — useful on the balance table when a covariate stays imbalanced and you want a second reading of what to try.

Using the adjusted sample

This procedure estimates no treatment effect itself — deliberately. The saved column feeds the analysis you actually want, with the design question and the outcome question kept separate (decide the adjustment before looking at outcomes):

  • After matching: Data → Select Cases, condition propensity_matched = 1, then run the outcome analysis (a t test, a regression, …) on the matched sample.
  • After weighting: Data → Weight Cases by propensity_weight, then run the outcome analysis on the weighted sample.

How this is computed

This section names which method each procedure prints — the estimator, the statistic, its degrees of freedom, and the tie, missing-value and weight rules — and links the recorded convention that explains the choice. The full index is the convention inventory; every number here is validated against independent packages per the validation suite.

  • The score — a binary logistic regression (IRLS, Wald z intervals) (Wald).
  • Matching — greedy 1:k nearest-neighbour without replacement, ATT, on the logit of the score, treated cases in descending score order, ties by dataset order; the caliper is a multiple of the SD of the logit (propensity conventions).
  • Balance — standardized mean differences over the unadjusted pooled SD √((s²_T + s²_C)/2) before and after, so both columns share one scale; IPTW weights 1/e and 1/(1 − e) for the ATE (propensity conventions · validation).
  • Reproducibility — deterministic: no random tie-breaking, so the same data gives the same match on every platform.

Reproducibility

Like every analysis, a run journals a syntax command, e.g.:

propensity_score treatment=treated, covariates=[age, bmi, smoker], method=match, caliper=0.2

or, for weighting under the treated-population estimand:

propensity_score treatment=treated, covariates=[age, bmi, smoker], method=weight, estimand=att

ratio (controls per treated), save_score, save_filter, save_weight and plot=false are recorded when they differ from the dialog's defaults. The same tool is available to the AI assistant, MCP and batch scripts — though the saved columns make it a mutating tool, so an assistant or MCP client running under the read-only profile is refused the save options and told why.

Scope (v1). Greedy nearest-neighbour and IPTW only — no optimal, genetic or full matching, and no doubly-robust estimators. And no causal magic: matching and weighting adjust only for the covariates you supplied. An unmeasured confounder passes straight through.