You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ggplot2绘制临床试验实际与预计招募曲线(日期X轴)

解决临床试验实际与预计招募对比图的直线叠加问题

你当前的问题出在geom_abline的参数设置上:x轴是日期格式,单位是天,但你直接用「每月20人」作为斜率,数值过大导致直线直接超出图表显示范围。下面给两种可行的修正方案:

方案一:修正geom_abline的斜率与截距

把每月招募人数换算成每日招募率,再结合起始日期的数值计算截距,确保直线和图表坐标轴匹配:

library(tibble)
library(ggplot2)

# 生成原始数据(这部分代码不变)
patient_ids <- paste0("Patient", 1:50)
recruitment_dates <- sample(seq(as.Date("2024-01-01"), as.Date("2024-12-31"), by = "day"), 50)
patients <- tibble(
  Patient_ID = patient_ids,
  Recruitment_Date = recruitment_dates
)
patients <- patients[order(patients$Recruitment_Date), ]
patients$Recruitment_Order <- 1:nrow(patients)

# 计算每日预计招募率:每月20人,按每月30天估算
daily_recruit_rate <- 20 / 30
# 计算截距:保证2024-01-01时预计招募人数为0
start_date_num <- as.numeric(as.Date("2024-01-01"))
intercept_val <- -daily_recruit_rate * start_date_num

# 绘图
ggplot(patients, aes(x = Recruitment_Date, y = Recruitment_Order)) +
  geom_point() +
  geom_abline(slope = daily_recruit_rate, intercept = intercept_val, color = "red", linetype = "dashed") +
  labs(x = "招募日期", y = "累计招募人数") +
  ggtitle("实际招募与预计招募对比")

方案二:用geom_line配合预计数据框(更直观推荐)

手动生成预计招募的完整时间序列数据,用折线图叠加,逻辑更清晰,也方便后续调整招募速率:

library(tibble)
library(ggplot2)

# 生成原始数据(这部分代码不变)
patient_ids <- paste0("Patient", 1:50)
recruitment_dates <- sample(seq(as.Date("2024-01-01"), as.Date("2024-12-31"), by = "day"), 50)
patients <- tibble(
  Patient_ID = patient_ids,
  Recruitment_Date = recruitment_dates
)
patients <- patients[order(patients$Recruitment_Date), ]
patients$Recruitment_Order <- 1:nrow(patients)

# 生成预计招募数据
start_date <- as.Date("2024-01-01")
end_date <- as.Date("2024-12-31")
# 生成每日日期序列
expected_dates <- seq(start_date, end_date, by = "day")
# 计算每日累计预计招募人数
expected_total <- floor((as.numeric(expected_dates) - as.numeric(start_date) + 1) * (20/30))

expected_df <- tibble(
  Date = expected_dates,
  Expected_Recruitment = expected_total
)

# 绘图
ggplot() +
  # 实际招募点
  geom_point(data = patients, aes(x = Recruitment_Date, y = Recruitment_Order)) +
  # 预计招募折线
  geom_line(data = expected_df, aes(x = Date, y = Expected_Recruitment), color = "red", linetype = "dashed") +
  labs(x = "招募日期", y = "累计招募人数") +
  ggtitle("实际招募与预计招募对比")

两种方案的区别:

  • 方案一更简洁,适合固定速率的预计招募场景;
  • 方案二更灵活,比如后续需要调整不同阶段的招募速率(如前3个月每月10人,之后每月25人),只需修改expected_total的计算逻辑即可。

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:15:33