Biostatistics & Survival Analysis
Greenwood Survival Standard Error and Log-Log Confidence Interval
Compute Kaplan-Meier survival S(t), Greenwood’s variance formula, and Kalbfleisch-Prentice log(-log S(t)) confidence bounds that never exceed 100% survival.
Reproduce why linear S(t) + 1.96*SE spills above 1.00 on high-survival cohorts
At each event time j with n_j patients at risk and d_j events, Kaplan-Meier survival updates via S_j = S_{j-1} * (1 - d_j / n_j) and Greenwood’s (1926) variance accumulates d_j / (n_j * (n_j - d_j)), giving SE_G = S(t) * SQRT(SUM(d_j / (n_j * (n_j - d_j)))). However, symmetric linear intervals S(t) +- 1.96 * SE_G routinely exceed 1.00 when survival is near 90%!
Check two early event intervals on 20 patients: Interval 1 has n_1 = 20, d_1 = 1 (B2:C2); Interval 2 has n_2 = 19, d_2 = 1 (B3:C3). Here S(t_2) = (19/20) * (18/19) = 0.9000, Greenwood sum = 1/380 + 1/342 = 1/180 = 0.005556, and SE_G = 0.90 * SQRT(1/180) = 0.0671. Naive linear upper bound 0.9000 + 1.96*0.0671 = 1.0315 (> 100%!), whereas Kalbfleisch-Prentice complementary log-log S(t)^(EXP(-1.959964 * SQRT(G_sum) / ABS(LN(S(t))))) stays strictly valid at 0.9740 (with lower bound 0.6560).
| Kaplan-Meier / CI Quantity | Formula Expression | Sample Output (S = 0.9000) |
|---|---|---|
| Product-Limit Survival S(t_2) | PRODUCT(1 - d_j / n_j) | 0.9000 |
| Greenwood Standard Error SE_G | S(t) * SQRT(SUM(d_j / (n_j * (n_j - d_j)))) | 0.0671 |
| Naive Linear Upper 95% (Bug) | S(t) + 1.959964 * SE_G | 1.0315 (Impossible > 1.00!) |
| Log-Log 95% Interval [L, U] | S(t)^EXP(+/- 1.959964 * SQRT(G_sum) / |LN(S)|) | [0.6560, 0.9740] (Strictly in (0,1)) |
Greenwood Standard Error SE_G Formula
Accumulate Greenwood’s hazard-variance increments d_j / (n_j * (n_j - d_j)) in column E and guard terminal wipeout n_j = d_j.
=IF(OR(D3 <= 0, D3 >= 1), "Boundary Survival (0 or 1)", ROUND(D3 * SQRT(SUM(E2:E3)), 4))Kalbfleisch-Prentice Complementary Log-Log 95% Upper & Lower Bounds Formula
Transform on the log(-log S(t)) scale (used as the default in R survival::survfit conf.type="log-log" and SAS LIFETEST) so both confidence limits remain strictly inside (0, 1) at every sample size.
=LET(s_km, D3, g_sum, SUM(E2:E3), IF(OR(s_km <= 0, s_km >= 1, g_sum <= 0), "Boundary Survival (0 or 1)", LET(se_cll, SQRT(g_sum) / ABS(LN(s_km)), ROUND(s_km^(EXP(-1.959964 * se_cll)), 4))))Try the example
Use the original values or change them to test your understanding.