Module 1 · Comparing survival curves

Lecture 2.3 onward. Reading: Lecture Notes Part 1, §1.5.

← Back to notes index

Lecture 2.3 — Comparing survival curves

The new setting: covariates

So far everything estimated $S(t)$ for a single sample — the data per subject was the pair $(X_i, \delta_i)$. Now each subject carries a third piece:

\[(X_i,\; \delta_i,\; \mathbf{Z}_i)\]
Symbol Meaning
$X_i$ censored event time, $\min(T_i, C_i)$
$\delta_i$ event indicator
$\mathbf{Z}_i$ covariates / characteristics of subject $i$

$\mathbf{Z}_i$ may be scalar (a single covariate — treatment arm, gender) or a $p \times 1$ vector of several covariates. The covariates themselves can be continuous, discrete, or time-varying.

When $\mathbf{Z}_i$ is scalar and binary, comparing survival across its two values is a two-group comparison — e.g. treatment vs. control. More generally we want a model relating survival to all covariates of interest.

Roadmap

Three levels of comparison, in increasing generality:

  1. Two-group comparison — treatment vs. control.
  2. Multigroup and stratified comparisons — more than two groups, or two groups compared within strata of another variable.
  3. Survival regression models — e.g. the Cox proportional hazards model, relating survival to arbitrary covariates.

Two-group comparison at a fixed time point

The simplest formal comparison: pick a single time point $t^$ — say $t^ = 3$ months — and compare the two groups’ survival there.

Let $S_0(\cdot)$ and $S_1(\cdot)$ be the survivor functions of the two groups (convention: $1$ = treatment, $0$ = control). The hypothesis test:

\[H_0 : S_1(t^*) = S_0(t^*) \qquad \text{vs} \qquad H_A : S_1(t^*) \ne S_0(t^*)\]

Equivalently, phrased as a difference:

\[H_0 : S_1(t^*) - S_0(t^*) = 0 \qquad \text{vs} \qquad H_A : S_1(t^*) - S_0(t^*) \ne 0\]

The difference form is the operational one — a difference of two estimates is a quantity we can put a confidence interval around:

\[\big\{\hat{S}_1(t^*) - \hat{S}_0(t^*)\big\} \;\pm\; 1.96 \sqrt{\hat{\sigma}_1^2(t^*) + \hat{\sigma}_0^2(t^*)}\]

where each $\hat{S}_j(t^)$ is the group’s Kaplan–Meier estimate and each $\hat{\sigma}_j^2(t^)$ its Greenwood variance estimate. The variances add because the two groups are assumed independent — that is what lets $\text{var}(\hat{S}_1 - \hat{S}_0) = \text{var}(\hat{S}_1) + \text{var}(\hat{S}_0)$. Reject $H_0$ if the interval does not contain $0$.

Single-time-point comparisons are common in clinical studies, and in personalized medicine (“what is this patient’s chance of surviving to $t^*$?”). But note the limitations:

  • Why $t^*$? — no principled way to choose a single or optimal time point.
  • Fishing — chosen post-hoc, the time point can be abused to manufacture significance.
  • Wasteful — it ignores everything the curves do at every other time; an inefficient use of the available information.

The picture makes the waste obvious — the test sees only the two dots at $t^*$, not the two curves:

t* S₁ S₀ S(t)

The fix — comparing the whole curves over the observed time frame — is the log-rank test.

The log-rank test

Log-rank test — compares $S_1(t)$ and $S_0(t)$ across the observed time frame by considering differences between the observed number of events and the expected number of events.

The hypothesis is now about the entire curves, not one time point:

\[H_0 : S_1(t) = S_0(t) \;\;\text{for all } t > 0 \qquad \text{vs} \qquad H_1 : S_1(t) \ne S_0(t) \;\;\text{for some } t > 0\]

Note the asymmetry in the quantifiers: the null requires the curves to agree everywhere; the alternative is satisfied by a difference anywhere.

Setup. Just as with Kaplan–Meier, the survival curves only change at event times — so those are the only places worth looking. Pool the data across both groups and order the unique event times of the combined sample:

\[t_{(1)} < t_{(2)} < \cdots < t_{(K)}\]

The 2×2 table. At the $k$-th event time, cross-tabulate group membership against what happened at that instant:

  No event Event  
Group 0 $n_{0k} - d_{0k}$ $d_{0k}$ $n_{0k}$
Group 1 $n_{1k} - d_{1k}$ $d_{1k}$ $n_{1k}$
  $n_k - d_k$ $d_k$ $n_k$

where, per group $j \in {0, 1}$:

\[\begin{aligned} n_{jk} &= \text{\# at risk in group } j \text{ at time } t_{(k)} \\[4pt] d_{jk} &= \text{\# of events in group } j \text{ at time } t_{(k)} \end{aligned}\]

The margins are the pooled counts from before: $n_k = n_{0k} + n_{1k}$ is everyone still at risk at $t_{(k)}$, and $d_k = d_{0k} + d_{1k}$ is everyone who had the event there. One such table exists at each of the $K$ event times — the log-rank test will combine information across all of them.

Observed vs. expected under the null

Focus on one cell of the table: $D_{1k}$, the number of events in Group 1 at time $t_{(k)}$. Under $H_0$ there is no association between group membership and the outcome, so conditional on the margins of the table:

\[D_{1k} \sim \text{Hypergeometric}(n_k,\; n_{1k},\; d_k)\]

Why hypergeometric? Think of it as an urn problem. At $t_{(k)}$ there are $n_k$ subjects at risk, of whom $d_k$ have the event at that instant. Under the null the event “chooses” its $d_k$ victims at random from the $n_k$ at risk, without regard to group. Group 1 occupies $n_{1k}$ of those $n_k$ slots — so the number of events landing in Group 1 is exactly a draw of $d_k$ balls from an urn with $n_{1k}$ marked ones out of $n_k$, without replacement.

From the properties of the hypergeometric, the expected number of Group 1 events is the natural proportional share:

\[E(D_{1k}) = \frac{n_{1k}\, d_k}{n_k}\]

Read it as: of the $d_k$ events, Group 1 should get the fraction $n_{1k}/n_k$ — its share of the risk set. If Group 1 holds 40% of the subjects at risk, under the null it should absorb 40% of the events at that time.

The building block of the test — observed minus expected at time $t_{(k)}$:

\[U_k = d_{1k} - E(D_{1k}) = d_{1k} - \frac{n_{1k}\, d_k}{n_k}\]

By construction, under $H_0$:

\[E(U_k) = 0\]

Each $U_k$ measures how far Group 1’s actual event count strays from its fair share at one event time. $U_k > 0$ means Group 1 had more events than expected there (worse survival); $U_k < 0$ means fewer (better survival). Under the null these deviations are just noise centered at zero; under the alternative they drift systematically in one direction — and summing them across the $K$ tables is what turns per-time noise into a test statistic.

The log-rank test statistic

One more ingredient: the variance of $U_k$, again from the hypergeometric,

\[V_k = \text{Var}(U_k) = \frac{n_{1k}\, n_{0k}\, (n_k - d_k)\, d_k}{n_k^2\,(n_k - 1)}\]

Now pool across the $K$ event times. The sum of the $U_k$’s, standardized by the square root of the summed variances, is approximately standard normal under $H_0$:

\[\frac{\sum_{k=1}^{K} U_k}{\sqrt{\sum_{k=1}^{K} V_k}} \;\sim\; N(0, 1)\]

Squaring it gives the equivalent chi-square form — the log-rank test statistic:

\[T_{LR} = \frac{\left[ \sum_{k=1}^{K} U_k \right]^2}{\sum_{k=1}^{K} V_k} \;\sim\; \chi^2_1\]

Under $H_0$, $T_{LR}$ follows a chi-square distribution with 1 degree of freedom (the square of a standard normal is exactly $\chi^21$) — so the p-value comes from the $\chi^2_1$ tail beyond the observed $T{LR}$.

Reading the construction. The numerator sums the raw deviations before squaring — so deviations in opposite directions at different times can cancel. The test has power against the alternative where one group is consistently better; it is weak against curves that cross.

Properties to keep in mind:

  • Equal weight per risk set — the numerator simply adds up the $K$ individual $U_k$ contributions, one per event time, with no weighting.
  • A consequence: the test can be sensitive to differences in the tails of the survivor functions — precisely where the risk sets are smallest and there is the least information.
  • Big differences late in the time scale may therefore have a large influence on the conclusion drawn about the entire time scale.