Test for equality of RMST across two or more groups.
rmst_test(
surv, tau, group, *, estimand="difference", strata=None, conf_level=0.95
)
Compares restricted mean survival time (RMST) up to a fixed time tau across groups using a z-test or t-test. Provides point estimate, standard error, confidence interval, and p-value for the null hypothesis of equal RMST.
For two groups, this is equivalent to a z-test on the RMST difference (default) or log-ratio (if estimand=“ratio”).
Parameters
surv: Surv
-
A right-censored Surv response (time-to-event data).
tau: float
-
The restriction time, typically a clinically relevant horizon (e.g., 365, 1825).
group: Any
-
Group membership for each observation. Can be array-like or categorical variable.
estimand: str = "difference"
-
Type of estimand: "difference" (default, RMST1 - RMST2), "ratio" (RMST1 / RMST2), or "percentage_difference" ((RMST1 - RMST2) / RMST2 * 100).
strata: Any | None = None
-
(Optional) Stratification variable for stratified RMST comparison. If provided, per-group RMST estimates are computed separately within each stratum and then combined using inverse-variance weights (Kaplan-Meier Greenwood variance). Strata in which either group is absent are skipped.
conf_level: float = 0.95
-
Confidence level for confidence intervals (the default is
0.95 for 95% CI).
Returns
RMSTResult
-
A result object containing estimate, standard error, confidence interval, test statistic, and p-value.
Details
For two groups (i=1,2), the RMST difference is:
\Delta = \mathrm{RMST}_1(\tau) - \mathrm{RMST}_2(\tau)
with standard error:
\mathrm{SE}(\Delta) = \sqrt{\mathrm{SE}(\mathrm{RMST}_1)^2 + \mathrm{SE}(\mathrm{RMST}_2)^2}
assuming independence. The z-statistic is Z = \Delta / \mathrm{SE}(\Delta), with two-tailed p-value from the standard normal.
For ratio estimand, the log-ratio variance uses the delta method:
\mathrm{SE}(\log R) = \sqrt{\frac{\mathrm{SE}_1^2}{\mathrm{RMST}_1^2} +
\frac{\mathrm{SE}_2^2}{\mathrm{RMST}_2^2}}
When strata is provided, per-group RMST values within each stratum are combined using inverse-variance (Greenwood) weights:
\widehat{\mathrm{RMST}}_k = \frac{\sum_s w_{ks}\, \mathrm{RMST}_{ks}}{\sum_s w_{ks}},
\quad w_{ks} = \frac{1}{\mathrm{SE}_{ks}^2}
The stratified SE is 1 / \sqrt{\sum_s w_{ks}}. The test statistic is then computed from the pooled group-level estimates.
Examples
Test whether the two sexes in the lung cancer dataset have significantly different one-year RMST:
import greenwood as gw
# Load data and build a right-censored response
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
# Test for one-year RMST difference between sex groups
result = gw.rmst_test(y, tau=365, group=lung["sex"])
result
RMSTResult(method='RMST difference (tau=365)', estimate=-55.9703, se=14.9581, 95% CI=[-85.2877, -26.6529], p_value=0.0001827)
Individual components of the result are accessible as attributes. For example, the point estimate and its p-value:
# Extract the RMST difference estimate
result.estimate
# Extract the p-value for the hypothesis test
result.p_value
To express the comparison as a ratio instead of a difference, set estimand="ratio". This reports \text{RMST}_1 / \text{RMST}_2 with a log-scale confidence interval:
# Compare RMST as a ratio instead of a difference
gw.rmst_test(y, tau=365, group=lung["sex"], estimand="ratio")
RMSTResult(method='RMST ratio (tau=365)', estimate=0.8118, se=0.0456, 95% CI=[0.7272, 0.9063], p_value=0.0002068)