R语言实现按exposure分组的重复测量Spaghetti图绘制
分组Spaghetti图(面条图)实现方案
问题背景
现有一份重复测量数据集,Score为因变量,exposure是所构建混合模型中的主要固定因子,数据集结构如下:
structure(list(ID = c(50L, 50L, 60L, 60L, 60L, 60L, 70L, 70L), Time = c(1L, 2L, 1L, 2L, 3L, 4L, 1L, 2L), Score = c(100L, 150L, 100L, 400L, -205L, -601L, 100L, 226L), exposure = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L)), class = "data.frame", row.names = c(NA, -8L))
需求为绘制Spaghetti图,展示各受试者Score随时间的变化趋势,同时体现不同exposure水平的效应,绘图时需按受试者所属exposure组别做视觉区分,无分组的参考效果如下:
现有初步代码未实现预期分组效果:
ggplot ( DB, aes ( x= Time, Y= Score, group_by=exposure, color = ID)+ geom_points()+ geom_line()+ theme_bw()
错误原因说明
原代码存在4个核心问题:
ggplot2的aes()映射中不存在group_by参数,分组控制需使用group参数- 纵轴映射参数为小写
y,原代码写为大写Y无法正确识别Score列 - 点图层函数名拼写错误,正确函数名为
geom_point(),无末尾s - 分组逻辑错误:面条图需要以单个受试者
ID为连线分组单位,才能保证同一个受试者的多次观测连成独立轨迹;若直接将分组设为exposure,会把同组所有受试者的观测点串成一条线,完全丢失个体轨迹信息,也无法通过视觉属性区分组别效应。
正确实现代码
library(ggplot2) # 读入示例数据 DB <- structure(list(ID = c(50L, 50L, 60L, 60L, 60L, 60L, 70L, 70L), Time = c(1L, 2L, 1L, 2L, 3L, 4L, 1L, 2L), Score = c(100L, 150L, 100L, 400L, -205L, -601L, 100L, 226L), exposure = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L)), class = "data.frame", row.names = c(NA, -8L)) # 预处理:将分类变量转为因子,避免被当作连续值处理 DB$ID <- as.factor(DB$ID) DB$exposure <- as.factor(DB$exposure) # 绘制分组面条图 ggplot(DB, aes(x = Time, y = Score)) + # 个体轨迹层:按ID连线,按exposure区分颜色,设置透明度避免线条遮挡 geom_line(aes(group = ID, color = exposure), linewidth = 1, alpha = 0.7) + # 观测点层:同样按exposure区分颜色 geom_point(aes(color = exposure), size = 2, alpha = 0.8) + # 可选:添加各组的平均趋势线(虚线),更直观展示exposure的整体效应 stat_smooth(aes(group = exposure, color = exposure), method = "lm", se = FALSE, linewidth = 1.5, linetype = "dashed") + # 修改图例标题 labs(color = "Exposure组别") + theme_bw()
可选优化方向
- 若同组受试者数量较多,可进一步调低
geom_line()的alpha值,减少线条重叠带来的视觉杂乱 - 可通过
scale_color_brewer(palette = "Set1")等配色函数调整组间颜色差异,让组别区分更明显 - 若需要单独展示每组的轨迹分布,可在代码末尾添加
facet_wrap(~exposure, ncol = 2)实现分面展示
内容的提问来源于stack exchange,提问作者Sari Katish
相关产品推荐
相关产品推荐

