Kaplan-Meier 生存曲线与 log-rank 检验计算器
比较两组的生存时间,不能用 t 检验,也不能比平均值。原因是删失: 有些受试者在研究结束时还活着,或者中途失访——你只知道他们「至少活了这么久」, 不知道确切时间。把这些人当成「死于最后一次随访」会低估生存, 直接扔掉他们会高估生存,两种做法都是错的。
Kaplan-Meier 估计量和 log-rank 检验就是为处理删失而设计的。
两步
Kaplan-Meier: S(t) = Π over 每个事件时刻 ti ≤ t (1 − d_i / r_i)
d_i = 该时刻的事件数,r_i = 该时刻仍在风险集中的人数
log-rank: 在每个事件时刻算一个 2×2 表,再合并
e_j = d_j · r0_j / r_j (组 0 的期望事件数)
v_j = r1_j · r0_j · d_j · (r_j − d_j) / [r_j² · (r_j − 1)]
χ² = [Σ(o_j − e_j)]² / Σ v_j (df = 1)
删失的人留在风险集里直到他被删失那一刻,之后退出。这一条就是全部关窍: 他贡献了「活到这个时间点」的信息,没有贡献「之后如何」的信息。
中位生存期为什么可能「算不出来」
中位生存期是 S(t) 第一次 ≤ 0.5 的那个时刻。如果曲线在研究结束时还在 0.5 以上, 中位生存期就是未达到,不能外推、不能写成「大于某个数」再当成点估计用。 本工具这种情况直接报「未达到」。
可以验算
用 Cox & Oakes《Analysis of Survival Data》Table 1.1 的白血病缓解期数据 (Freireich 1963 的 6-MP vs 安慰剂试验,每组 21 人,时间单位:周):
| 量 | 本工具 | 讲义发表值 |
|---|---|---|
| Σ(o − e) | −10.2505 | +10.251 |
| Σ v | 6.2570 | 6.257 |
| χ²(df=1) | 16.7929 | 16.793 |
| 中位生存 6-MP | 23 | 23 |
| 中位生存 安慰剂 | 8 | 8 |
发表值出自密歇根大学生物统计讲义(Yi Li)对该表的完整演算。 点开工具就是这组数据,可以直接核。
Σ(o − e) 的符号相反是对的:讲义以安慰剂组为参照组,本工具以第 1 组 (表单里是 6-MP)为参照,绝对值完全相同。χ² 取平方,与参照组选谁无关。
能对上中间量比只对上最终统计量硬得多——只对最终值有可能是两个错互相抵消, Σ(o−e) 和 Σv 同时对上说明每一步都对。
适用边界
- log-rank 回答的是「两条曲线有没有差别」,不是「差多少」。 p 值再小也不是效应量。 要风险比(HR)得做 Cox 比例风险回归,本工具不做。 不做的理由不只是省事:就拿上面那份白血病数据,四种都站得住的算法给出四个 HR—— O/E 比值法 0.239、Peto 一步法 0.194、Cox 用 Breslow 处理结法 0.221、 Cox 用 Efron 0.208。极差 23%。 连「做 Cox 回归」本身都不是一个确定的答案:同一个模型, 只是同一时刻并发事件(结)的处理方式不同,就差了 6%。 所以报 HR 必须同时交代用的是哪种算法,而一个只甩给你一个数字的在线工具 做不到这件事——这就是本工具只做检验、不报效应量的原因。
- log-rank 假定比例风险:两组的风险比在整个随访期里大致恒定。 如果两条曲线交叉,log-rank 会把前后相反的差异抵消掉, 得出「没有差别」的结论——而这时候差别其实很大,只是方向变了。 曲线交叉时该换 Renyi 检验或限制平均生存时间(RMST)这类方法。
- 只做两组比较。多组需要推广的 log-rank(df = 组数 − 1),本工具不支持。
- 删失必须与预后无关(无信息删失)。如果病重的人更容易失访, KM 会系统性高估生存,这是方法本身管不了的,只能靠研究设计。
- 事件数少时 χ² 近似不可靠。本工具在总事件数 < 10 时给出提示。
常见问题
状态那一列填 1 还是 0?
**1 表示观察到了事件**(死亡、复发、达到终点),**0 表示删失**(研究结束时还没发生,或中途失访)。填反会把结论完全颠倒过来——删失被当成事件,生存曲线会一路掉到 0。很多软件用 `+` 号标记删失(比如 `6+` 表示至少 6 周),那种写法对应的就是状态 0。
为什么不能直接比两组的平均生存时间?
因为删失。研究结束时还活着的人,你只知道他「至少活了这么久」。把这个时间当成实际生存时间会**低估**生存,把这些人删掉会**高估**生存(活得久的更容易被删失)。Kaplan-Meier 的做法是让删失的人留在风险集里直到他被删失那一刻,之后退出——他贡献了「活到这里」的信息,没贡献「之后如何」的信息。
中位生存期显示「未达到」是什么意思?
说明到随访结束时,生存曲线还没降到 0.5,也就是**超过一半的人还没发生事件**。这种情况下中位生存期在数据里不存在,不能外推。正确的报告方式是「中位生存期未达到」,而不是写成「> 某个数」再当点估计用。想比较两组仍然可以用 log-rank——它用的是全部时间点的信息,不依赖中位数。
p 值很小,是不是说明效果很大?
不是。**log-rank 回答「两条曲线有没有差别」,不回答「差多少」。**p 值同时取决于效应大小和样本量:样本够大时,很小的差别也能给出极小的 p。要效应量得做 Cox 比例风险回归得到风险比(HR)。而 HR 本身也不是一个唯一的数:拿本工具默认那份白血病数据,O/E 比值法得 0.239、Peto 一步法 0.194、Cox 配 Breslow 结法 0.221、Cox 配 Efron 0.208,极差 23%——**连「做 Cox 回归」都要再问一句用哪种结法**,光这一项就差 6%。所以本工具只做检验不报 HR:甩给你一个不说明算法的数字,比不给更容易被误用。
两条生存曲线交叉了,log-rank 结果可信吗?
**不可信,而且它的失效方式很隐蔽。** log-rank 把各时刻的 (o − e) 累加起来,曲线交叉意味着前期和后期的差异符号相反,加起来互相抵消,于是给出「没有差别」——而实际差别可能很大,只是方向变了。这是 log-rank 最常被忽略的前提(比例风险)。曲线交叉时该换 Renyi 检验、加权 log-rank,或者直接报限制平均生存时间(RMST)的差值。
能做三组以上的比较吗?
本工具只做两组。多组需要推广的 log-rank 检验(df = 组数 − 1),统计量形式不同,不是把两两比较拼起来。如果你只想知道「几组里有没有差别」,需要多组版本;如果要做两两比较,记得对 p 值做多重比较校正——本站有 [Benjamini-Hochberg FDR 校正](../fdr-bh/)。
相关工具
药代动力学非房室分析(NCA):AUC、半衰期、清除率在线计算
贴浓度-时间数据和给药剂量,算出 AUC(0→t)、外推到无穷的 AUC、λz 与半衰期、MRT、清除率和表观分布容积;默认用 linear-up/log-down,并算给你看纯线性梯形会高估多少。
ROC 曲线与 AUC 计算器(含 Hanley-McNeil 置信区间)
贴阳性组与阴性组的评分,算出 ROC 表、AUC(梯形法与一致对法互相校验)、Hanley-McNeil 置信区间、Youden J 最优阈值和 Mann-Whitney 检验;也可只填已发表的 AUC 与样本量求置信区间。
诊断试验四格表计算器:灵敏度 / 特异度 / 阳性预测值
输入 TP/FP/FN/TN 四格,一次算出灵敏度、特异度、阳性与阴性预测值、似然比与约登指数,给出 95% Wilson 置信区间,并可用贝叶斯公式更新后验概率。