Skip to content

Return the RMST estimator's sampling variance (Greenwood, K&M eq. 4.4.4) from restricted_mean_survival_time for Kaplan-Meier fits - #1696

Open
azrabano23 wants to merge 1 commit into
CamDavidsonPilon:masterfrom
azrabano23:fix-1682-rmst-variance
Open

Return the RMST estimator's sampling variance (Greenwood, K&M eq. 4.4.4) from restricted_mean_survival_time for Kaplan-Meier fits#1696
azrabano23 wants to merge 1 commit into
CamDavidsonPilon:masterfrom
azrabano23:fix-1682-rmst-variance

Conversation

@azrabano23

Copy link
Copy Markdown

Closes #1682

What was wrong

restricted_mean_survival_time(model, t, return_variance=True) returned

E[min(T,t)²] − E[min(T,t)]²

which is the variance of the truncated random variable min(T, t) — a property of the survival distribution itself — not the sampling variance of the RMST estimator. Anyone using it to build a standard error, confidence interval, or 2-sample z-test silently got grossly inflated SEs and conservative p-values. On the bundled waltons data (miR-137 group, τ=10) the implied SE was ~0.719 where the correct SE is ~0.123 — the variance was ~34× too large, and a 2-sample test on waltons moved from p≈0.81 to p≈0.15 once the correct variance is used (see #1682 for the full reproduction).

The fix

For a KaplanMeierFitter fit to right-censored data, return_variance=True now returns the Greenwood-based sampling variance of the RMST estimator, Klein & Moeschberger (2003), Survival Analysis: Techniques for Censored and Truncated Data, eq. 4.4.4:

Var(RMST(τ)) = Σ_i [ ∫_{t_i}^{τ} Ŝ(u) du ]² · d_i / (n_i (n_i − d_i))

summed over distinct event times t_i ≤ τ, with d_i events out of n_i at risk (terms with n_i = d_i contribute 0, as in survRM2). This is the same estimator R's survRM2::rmst2 uses. It's computed exactly from model.event_table and the KM step function — no numerical integration.

Backwards compatibility

Validation

  • waltons miR-137, τ=10: new result RMST = 9.794118, SE = 0.123245 — matches the survRM2::rmst2 reference values reported in restricted_mean_survival_time(..., return_variance=True) returns variance of the truncated RV, not the sampling variance — silently produces wrong p-values #1682 (RMST 9.794, SE 0.123) and PR includes RMST, difference in RMST and confidence intervals #1526's fixture for the same case.
  • An independent hand implementation of eq. 4.4.4 (written directly from raw (T, E) arrays, separate from the library code) agrees to machine precision across 5 waltons group/τ configurations and a synthetic exponential dataset with ~45% independent censoring.
  • Bootstrap check on the synthetic censored dataset (n=80, 400 resamples): resampling variance 0.4590 vs Greenwood 0.4742 (ratio 0.97).
  • New tests cover: the survRM2 reference values, the hand-computed Greenwood formula on a small censored dataset, and the warning on non-KM inputs. Existing RMST tests in lifelines/tests/utils/test_utils.py still pass unchanged, including the truncated-RV variance test for ExponentialFitter (test_rmst_variance) and the left-censoring edge case.

…ator's sampling variance for Kaplan-Meier fits

restricted_mean_survival_time(..., return_variance=True) returned
E[min(T,t)^2] - E[min(T,t)]^2, the variance of the truncated random
variable -- a property of the distribution -- rather than the sampling
variance of the RMST estimator, silently inflating standard errors and
p-values built from it.

For a KaplanMeierFitter fit to right-censored data, return the
Greenwood-based sampling variance (Klein & Moeschberger 2003,
eq. 4.4.4), matching R's survRM2::rmst2. For parametric fitters and
precomputed survival functions, keep the previous value for backwards
compatibility but emit a StatisticalWarning that it is not a sampling
variance; document both behaviours in the docstring.

Closes CamDavidsonPilon#1682
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant