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

如何使用R在时间进程图中添加各组各时间点的观测数标注

ggplot2时间进程图标注分组各时间点样本量实现方案

你原有代码的geom_text层存在逻辑问题:固定y=0会让标签全部堆叠在x轴底部,直接映射原始lac列作为标签会输出所有原始观测的乳酸值,无法得到分组样本量标注。以下是两种可直接复用的实现方式:

方法1:原生stat_summary层自动统计(无需提前处理数据)

完全适配你现有代码的统计逻辑,不需要提前汇总数据,直接替换原有错误的geom_text层即可,修正后的完整代码如下:

ggplot(df, aes(x=time_nrp, y=lac, color=as.factor(outcome)))+ 
  geom_point(stat="summary", fun=mean, size=4)+
  geom_line(stat="summary", fun=mean, aes(group=as.factor(outcome)))+
  stat_summary(fun.data=mean_se, geom="errorbar", width=0.01)+
  # 新增样本量标注层,自动按分组+时间点计数
  stat_summary(
    fun = length,
    geom = "text",
    aes(label = after_stat(n)),
    vjust = -1.2, # 调整垂直位置,标签放在均值点上方,避免遮挡图形
    size = 5,
    show.legend = FALSE # 避免文本层额外生成冗余图例
  )+
  xlab("NRP Time (hours)")+
  ylab("Lactate (mmol/l)")+
  theme_bw()+
  ggtitle("Panel A")+ 
  theme(plot.title = element_text(hjust=0.5))+
  theme(text=element_text(family="Helvetica", size=20))+
  scale_color_manual(name="Outcome", 
                     breaks=c("0", "1"),
                     labels=c("Negative", "Positive"),
                     values = c("#E12000", "#002F80"))

针对你提供的示例测试数据(变量名为group/time/lactate),适配后的可运行测试代码:

# 读入示例数据
df_demo <- read.table(text = "id  group time lactate     
 1     A   1   1.2
 1     A   2   1.1
 1     A   3   1.3
 2     B   1   0.8
 2     B   2   0.7
 2     B   3   0.9
 3     A   1   0.7
 3     A   2   0.9
 3     A   3   1.3
 4     B   1   0.5
 4     B   2   0.6
 4     B   3   0.7", header = TRUE)

# 示例数据绘图
ggplot(df_demo, aes(x=time, y=lactate, color=group))+ 
  geom_point(stat="summary", fun=mean, size=4)+
  geom_line(stat="summary", fun=mean, aes(group=group))+
  stat_summary(fun.data=mean_se, geom="errorbar", width=0.01)+
  stat_summary(
    fun = length,
    geom = "text",
    aes(label = after_stat(n)),
    vjust = -1.2,
    size = 5,
    show.legend = FALSE
  )+
  xlab("Time point")+
  ylab("Lactate (mmol/l)")+
  theme_bw()+
  theme(text=element_text(family="Helvetica", size=20))

该方案的优势:

  • 和原有代码的均值、误差线统计逻辑完全一致,不会出现分组、时间点匹配错位
  • 直接调用原始数据绘图,后续增删观测不需要修改标注相关代码
  • 仅需调整vjust/hjust参数即可快速修改标签位置,适配不同出图尺寸

方法2:提前汇总数据标注(适合自定义标签格式)

如果需要自定义标签样式(比如显示为n=3的格式),可以先通过dplyr按分组汇总统计指标,再单独映射文本层,示例代码如下:

library(dplyr)
# 提前分组汇总均值、标准误、样本量
df_summary <- df %>%
  group_by(outcome, time_nrp) %>%
  summarise(
    mean_lac = mean(lac, na.rm = TRUE),
    se_lac = sd(lac, na.rm = TRUE)/sqrt(n()),
    n = n(),
    .groups = "drop"
  )

# 基于汇总后的数据绘图
ggplot(df_summary, aes(x=time_nrp, y=mean_lac, color=as.factor(outcome)))+
  geom_point(size=4)+
  geom_line(aes(group=as.factor(outcome)))+
  geom_errorbar(aes(ymin = mean_lac - se_lac, ymax = mean_lac + se_lac), width=0.01)+
  # 自定义标签格式
  geom_text(aes(label = paste0("n=", n)), vjust = -1.2, size=5, show.legend = FALSE)+
  # 后续坐标轴、主题、颜色设置和原代码完全一致
  xlab("NRP Time (hours)")+
  ylab("Lactate (mmol/l)")+
  theme_bw()+
  ggtitle("Panel A")+ 
  theme(plot.title = element_text(hjust=0.5))+
  theme(text=element_text(family="Helvetica", size=20))+
  scale_color_manual(name="Outcome", 
                     breaks=c("0", "1"),
                     labels=c("Negative", "Positive"),
                     values = c("#E12000", "#002F80"))

注意事项

  • 如果数据存在缺失值,所有统计函数内记得加na.rm = TRUE参数,避免计数偏差
  • 标签的size、vjust参数可根据实际出图的尺寸、误差线长度调整,避免和点、误差线、坐标轴元素重叠
  • 如果需要将标签放在x轴底部对齐,可将文本层的y映射为固定值(略高于x轴刻度最小值),注意按分组做微小的水平位置偏移,避免同时间点两个分组的标签重叠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:54:21