Kaplan-Meier生存曲线详解:原理、应用场景与绘图方法

系统介绍Kaplan-Meier生存曲线的原理、适用场景、计算逻辑与R/Python/GraphPad等软件的绘图方法,帮助科研人员正确理解和使用这张经典图表。

更新于2026年8月5日

Kaplan-Meier生存曲线详解:原理、应用场景与绘图方法

在临床研究和流行病学中,我们经常面对一个现实问题:随访时间长短不一,有人中途失访,有人研究结束时还没有发生终点事件。这时候如果简单用“死亡率”或“平均生存时间”来总结数据,很容易产生偏差。Kaplan-Meier 生存曲线(简称KM曲线)正是为解决这类“不完整观察”而生的经典工具。它自1958年由Edward L. Kaplan和Paul Meier提出后,已经成为医学论文中最常见的图形之一。

本文尽量用通俗但准确的方式,把这张“阶梯状”的曲线讲清楚,并给出实际绘图思路。

生存分析的核心是“时间到事件”数据。事件不一定是死亡,也可以是疾病进展、复发、再入院、设备故障,甚至客户流失。关键难点在于删失(censoring):有些研究对象在研究结束时还没发生事件,或者中途失访、退出。如果直接剔除这些人,会损失信息;如果把他们当成“没发生事件”硬算,又会高估生存概率。

Kaplan-Meier方法通过“乘积限估计”巧妙地处理了删失,让我们在不完全数据下仍能得到无偏的生存概率估计。它不需要假设生存时间服从某种特定分布(非参数方法),因此在样本量中等、分布未知时特别实用。理解并正确绘制KM曲线,是科研人员做生存分析、读懂临床论文的基本功。

什么是Kaplan-Meier 生存曲线?

简单来说,Kaplan-Meier曲线描述的是:在任意时间点t,研究对象尚未发生终点事件的概率,即生存函数S(t)。

曲线从时间0、生存概率1.0(100%)出发。每当有事件发生,曲线就向下“掉一格”(阶梯状下降);删失的个体则用小竖线或“+”标记在对应时间点,但不会引起曲线下降。水平段表示这段时间内没有事件发生。

其计算公式本质是条件概率的连乘:

在每个事件发生时间点ti,用“当时仍处于风险中的人数中,未发生事件的比例”去更新之前的累计生存概率。具体来说:

Kaplan-Meier 生存曲线计算公式

其中di是ti时刻发生事件的人数,ni是ti时刻仍处于风险集中的人数(包括后续会删失的人)。

这种“只在事件发生时更新”的特性,造就了它独特的阶梯外观。曲线右侧往往变得更“平坦”,因为剩余风险集人数变少,估计也更不稳定——这正是读图时需要警惕的地方。

下面是一张典型的KM曲线示例(带95%置信区间和删失标记):

KM曲线示例

(来源:Wikimedia Commons,CC0公共领域,作者Accountalive)

而接下来这张图,是根据肿瘤反应分层的实体瘤化疗后生存率。该图摘自 Coltman等人的论文。该研究可能是第一个典型的“阶梯式”Kaplan-Meier 生存曲线医学生存表现形式。

KM曲线示例

从曲线上我们还能直接读出中位生存时间(曲线穿过0.5时对应的时间点),以及特定时间点的生存率(如1年、3年、5年生存率)。

Kaplan-Meier 生存曲线适用场景

KM曲线几乎出现在所有涉及“时间到事件”的临床研究中,尤其是:

1. 肿瘤学:总生存(OS)、无进展生存(PFS)、无病生存(DFS)是最常见的终点。比较不同治疗组、不同分子分型、不同分期的患者生存差异时,几乎必画KM曲线。

2. 心血管疾病与重症医学:再入院时间、主要不良心血管事件(MACE)发生时间、机械通气撤机时间等。

3. 移植与感染病学:移植物存活、病毒清除、抗生素治疗失败时间。

4. 非医学领域:可靠性工程(设备故障时间)、社会学(失业持续时间)、市场营销(客户流失时间)等。

它特别适合以下情况:

- 存在右删失数据;

- 不需要(或不适合)假设参数分布;

- 主要目的是描述和比较组间生存差异(后续可用Log-rank检验)。

需要注意的是,当存在竞争风险(例如研究癌症特异性死亡时,患者先死于其他原因)时,普通KM曲线会高估事件发生率,这时应改用累计发生率函数(Aalen-Johansen估计)。另外,KM曲线本身不直接处理协变量影响,若要同时调整多个因素,通常需要进一步做Cox比例风险回归。

如何画Kaplan-Meier 生存曲线

实际绘图并不复杂,关键是数据准备正确。通常需要三列核心数据:

  • 观察时间(Time):从起点到事件或删失的时间;
  • 状态(Status/Event):1=发生事件,0=删失;
  • 分组变量(可选):用于比较不同组别。

1. 用R绘制(推荐,学术期刊最常见)

R

library(survival)

library(survminer)

# 假设数据框df中有time, status, group三列

fit <- survfit(Surv(time, status) ~ group, data = df)

ggsurvplot(fit,

conf.int = TRUE, # 显示置信区间

risk.table = TRUE, # 显示风险表

pval = TRUE, # 显示Log-rank P值

legend.title = "组别",

xlab = "时间(月)",

ylab = "生存概率",

break.time.by = 6)

2. 用Python(lifelines库)

python

from lifelines import KaplanMeierFitter

import matplotlib.pyplot as plt

kmf = KaplanMeierFitter()

kmf.fit(df['time'], event_observed=df['status'], label='整体')

kmf.plot_survival_function()

plt.xlabel('时间')

plt.ylabel('生存概率')

plt.show()

分组比较时循环拟合不同组别即可。

3. 其他常用软件

  • GraphPad Prism:菜单里直接选“Survival”,操作最友好,适合不写代码的研究者。
  • SPSS:Analyze → Survival → Kaplan-Meier,勾选相应选项即可输出曲线和表格。
  • Stata、SAS也都有成熟命令。

绘图时建议注意几点:

  • 始终标注删失点;
  • 附上风险表(Number at risk),让读者知道每个时间点还剩多少人;
  • 报告中位生存时间及其置信区间;
  • 组间比较用Log-rank检验,并给出P值;
  • 如果曲线后期风险集很小,可考虑截断显示,并在图注中说明。

最后

Kaplan-Meier曲线看起来只是一张阶梯图,背后却承载着对“不完整数据”的严谨处理。它既直观又强大,是连接原始随访数据与临床结论的重要桥梁。真正用好它,不仅要会画,更要会读——理解每一步下降的含义、删失的影响、以及曲线后期的不确定性。

如果你正在做生存分析,建议从模拟小数据开始手动算一遍生存概率,再对照软件输出,这样印象会深刻很多。希望这篇介绍能帮你在读文献和写论文时更从容一些。

撰稿人
标签
学术科研数据分析
目录
订阅邮件
订阅我们的邮箱后可提前获得AJE作者资源的文章,享受AJE服务的折扣,以及更多的优惠

查看 "隐私协议"

AJE提供一系列科研支持服务,助力论文成功发表!

AJE为您提供英文论文润色、学术论文翻译、期刊选择、文稿排版等一系列学术服务,我们希望可以帮助您充分发挥您的研究潜力,助力您成功将论文发布在国际期刊上。