如何在R中绘制相对于参考组的对比散点图及回归线?
R实现参考仪器与其他仪器测量值的配对散点图+回归线
核心思路
不需要转宽表造成数据混乱,而是通过数据连接将参考仪器的测量值与对应样本的其他仪器测量值精准配对,再利用ggplot的分组映射自动生成不同仪器的散点和回归线。
示例代码
1. 构造符合你需求的示例数据
library(tidyverse) set.seed(123) # 模拟数据结构:样本+仪器标识+多测量列 df <- tibble( Sample = rep(1:50, 3), Instrument = rep(c("Ref", "Test1", "Test2"), each = 50), M1 = c(rnorm(50, 10, 1), rnorm(50, 10.2, 1.1), rnorm(50, 9.8, 0.9)), M2 = c(rnorm(50, 20, 2), rnorm(50, 20.5, 2.2), rnorm(50, 19.7, 1.8)) )
2. 数据整理:配对参考值与测试值
方式1:批量处理所有测量列(M1/M2/...)
通过转长格式+数据连接,一次性处理所有测量项:
# 提取参考仪器的所有测量值,转长格式 ref_long <- df %>% filter(Instrument == "Ref") %>% select(Sample, starts_with("M")) %>% pivot_longer(cols = starts_with("M"), names_to = "Measure", values_to = "Ref_Value") # 提取其他仪器的所有测量值,转长格式 test_long <- df %>% filter(Instrument != "Ref") %>% select(Sample, Instrument, starts_with("M")) %>% pivot_longer(cols = starts_with("M"), names_to = "Measure", values_to = "Test_Value") # 按样本+测量项配对,保证每个测试值对应同样本的参考值 combined <- inner_join(test_long, ref_long, by = c("Sample", "Measure"))
方式2:仅处理单个测量列(如M1)
如果只需要分析某一个测量项,简化代码:
# 提取参考仪器M1值 ref_m1 <- df %>% filter(Instrument == "Ref") %>% select(Sample, Ref_M1 = M1) # 提取其他仪器M1值 test_m1 <- df %>% filter(Instrument != "Ref") %>% select(Sample, Instrument, Test_M1 = M1) # 配对数据 combined_m1 <- inner_join(test_m1, ref_m1, by = "Sample")
3. 绘制散点图+回归线
批量处理的绘图代码(分面展示所有测量项)
ggplot(combined, aes(x = Ref_Value, y = Test_Value, color = Instrument)) + geom_point(alpha = 0.7, size = 1.5) + # alpha降低重叠遮挡 geom_smooth(method = "lm", se = FALSE, linewidth = 1) + # 线性回归线,se=FALSE移除置信区间 facet_wrap(~Measure, scales = "free") + # 按测量项分面展示 labs(x = "参考仪器测量值", y = "测试仪器测量值", color = "仪器") + theme_bw()
单个测量项的绘图代码
ggplot(combined_m1, aes(x = Ref_M1, y = Test_M1, color = Instrument)) + geom_point() + geom_smooth(method = "lm", se = TRUE) + # se=TRUE保留置信区间 labs(x = "参考仪器M1测量值", y = "测试仪器M1测量值", color = "仪器") + theme_minimal()
关键说明
- 无需
group_by直接绘图:ggplot的aes(color=Instrument)会自动按仪器分组,生成对应颜色的散点和回归线,无需额外分组操作。 - 避免宽表混乱:通过
inner_join保证样本配对的准确性,不会出现转宽表时的索引错位问题。 - 扩展性强:批量处理代码可直接适配更多测量列(如M3/M4),无需修改核心逻辑。
内容的提问来源于stack exchange,提问作者Carl S
相关产品推荐
相关产品推荐

