# 加载包
library(dplyr)
library(forcats)
library(ggplot2)
library(patchwork)瀑布图
瀑布图(Waterfall plot)是肿瘤临床试验中展示每例患者最佳肿瘤应答的标准图形。每根柱代表一名患者,按靶病灶直径总和相对基线的最佳百分比变化排序,柱子通常按 RECIST 应答类别(CR、PR、SD、PD)着色 [1]。瀑布图直观回答“应答有多深?”,与 Kaplan-Meier 生存曲线(回答“患者活了多久?”)互为补充,并常与展示每例患者肿瘤大小纵向轨迹的蜘蛛图(spider plot)搭配出现。
瀑布图可能在视觉上高估应答率,因为它只显示最佳变化,且不可测量的进展可能被低估 [2]。请将瀑布图与蜘蛛图配合使用,并以数字形式报告应答率。
示例

环境配置
系统要求:跨平台(Linux/MacOS/Windows)
编程语言:R
依赖包:
dplyr;forcats;ggplot2;patchwork
sessioninfo::session_info("attached")─ Session info ───────────────────────────────────────────────────────────────
setting value
version R version 4.6.1 (2026-06-24)
os Ubuntu 24.04.5 LTS
system x86_64, linux-gnu
ui X11
language (EN)
collate C.UTF-8
ctype C.UTF-8
tz UTC
date 2026-10-29
pandoc 3.1.3 @ /usr/bin/ (via rmarkdown)
quarto 1.10.19 @ /usr/local/bin/quarto
─ Packages ───────────────────────────────────────────────────────────────────
! package * version date (UTC) lib source
P dplyr * 1.2.1 2026-04-03 [?] RSPM
P forcats * 1.0.1 2025-09-25 [?] RSPM
P ggplot2 * 4.0.3.9000 2026-10-26 [?] Github (tidyverse/ggplot2@b638d65)
P patchwork * 1.3.2 2025-08-25 [?] RSPM
[1] /home/runner/.cache/R/renv/library/Bizard-5140bdc6/linux-ubuntu-noble/R-4.6/x86_64-pc-linux-gnu
[2] /home/runner/work/_temp/Library
[3] /opt/R/4.6.1/lib/R/library
* ── Packages attached to the search path.
P ── Loaded and on-disk path mismatch.
──────────────────────────────────────────────────────────────────────────────
数据准备
所需输入是每例患者一行的数据,至少包含靶病灶的最佳百分比变化和 RECIST 类别。由于 R 没有内置临床试验的患者级数据集,我们模拟一个贴近 II 期临床试验的队列:40 例患者的最佳变化遵循中等活性方案的预期分布(RECIST 阈值:PR 要求缩小 ≥30%,PD 要求增长 ≥20%)[1]。分析真实数据时,将模拟部分替换为 read.csv("your_recist_data.csv") 即可——列结构完全相同。
set.seed(2026)
n <- 40
response <- sample(c("CR", "PR", "SD", "PD"), n,
prob = c(0.05, 0.40, 0.30, 0.25), replace = TRUE)
best_change <- round(case_when(
response == "CR" ~ -runif(n, 95, 100), # 完全缓解:几乎完全缩小
response == "PR" ~ -runif(n, 30, 92), # 部分缓解:缩小 30-90%
response == "SD" ~ runif(n, -25, 18), # 疾病稳定
response == "PD" ~ runif(n, 22, 120) # 疾病进展
), 1)
wf <- data.frame(
patient = paste0("P", sprintf("%02d", seq_len(n))),
best_change = best_change,
response = response
)
head(wf) patient best_change response
1 P01 -5.9 SD
2 P02 -19.3 SD
3 P03 -78.5 PR
4 P04 -89.7 PR
5 P05 -6.9 SD
6 P06 -90.6 PR
再为配套的蜘蛛图模拟纵向轨迹:从基线到最佳变化的近似直线漂移叠加较小的周间噪声,进展者的病情在后期加速。
set.seed(2027)
weeks <- seq(0, 48, 6)
spider <- do.call(rbind, lapply(seq_len(nrow(wf)), function(i) {
k <- length(weeks)
endpoint <- wf$best_change[i]
base <- approx(x = c(1, k), y = c(0, endpoint), xout = 1:k)$y
noise <- runif(k, -4, 4)
if (wf$response[i] == "PD") noise <- noise + seq(0, 12, length.out = k) # 后期加速
data.frame(patient = wf$patient[i], week = weeks,
change = round(pmin(base + noise, 130), 1),
response = wf$response[i])
}))
head(spider) patient week change response
1 P01 0 -2.6 SD
2 P01 6 -1.5 SD
3 P01 12 -3.5 SD
4 P01 18 -0.6 SD
5 P01 24 -4.6 SD
6 P01 30 -5.2 SD
可视化
1. 基础瀑布图
按最佳变化排序患者并翻转坐标轴,得到经典的发表级版式。
p1 <- wf %>%
mutate(patient = fct_reorder(patient, best_change)) %>%
ggplot(aes(patient, best_change)) +
geom_col(fill = "#4393C3", width = 0.75) +
coord_flip() +
labs(x = NULL, y = "Best % change from baseline") +
theme_bw()
p1
2. 按 RECIST 着色并带参考线的瀑布图
按应答类别为柱子着色,并添加 RECIST 参考线:−30% 是部分缓解的边界,+20% 是进展的边界(正式定义中,PD 还要求直径总和绝对值增加至少 5 mm)。
recist_colors <- c(CR = "#1B7837", PR = "#66BD63", SD = "#FFB300", PD = "#C51B7D")
p2 <- wf %>%
mutate(patient = fct_reorder(patient, best_change)) %>%
ggplot(aes(patient, best_change, fill = response)) +
geom_col(width = 0.75) +
geom_hline(yintercept = c(-30, 20), linetype = "dashed", color = "grey35") +
scale_fill_manual(values = recist_colors, name = "RECIST") +
coord_flip() +
labs(x = NULL, y = "Best % change from baseline") +
theme_bw() +
theme(legend.position = "top")
p2
两条虚线使应答率(低于 −30% 的柱子)与疾病控制率(低于 +20% 的所有柱子)一目了然。
3. 配套蜘蛛图
p3 <- spider %>%
ggplot(aes(week, change, group = patient, color = response)) +
geom_hline(yintercept = c(-30, 20), linetype = "dashed", color = "grey35") +
geom_line(alpha = 0.75, linewidth = 0.6) +
scale_color_manual(values = recist_colors, name = "RECIST") +
labs(x = "Weeks on treatment", y = "% change from baseline") +
theme_bw() +
theme(legend.position = "top")
p3
4. 组合图
p2 + p3 + plot_annotation(
title = "Best tumor response and its longitudinal trajectories",
tag_levels = "A"
)
两图对照阅读:柱子给出应答深度,折线给出应答的形态——早期缩小者、晚期进展者和原发难治者只有通过蜘蛛图才能区分。
应用
瀑布图在临床肿瘤学论文和 FDA/EMA 申报材料中无处不在,用于总结某方案抗肿瘤活性;下方的”瀑布图 + 蜘蛛图”组合即为典型呈现形式。

参考文献
[1] Eisenhauer EA, Therasse P, Bogaerts J, et al. New response evaluation criteria in solid tumours: revised RECIST guideline (version 1.1). Eur J Cancer. 2009;45(2):228-247. doi:10.1016/j.ejca.2008.10.026
[2] Kim MS, Prasad V. Assessment of accuracy of waterfall plot representations of response rates in cancer treatment published in medical journals. JAMA Netw Open. 2019;2(5):e193981. doi:10.1001/jamanetworkopen.2019.3981
