如何在R中平滑绘图线条并添加S型最佳拟合线
问题与解决方案
原始问题
已有以下R代码生成滴定实验的散点图:
ggline(Titration.Aug.9,x="Dilution",y="X..bound",color="Sample")+ scale_x_continuous(trans="log10",labels=trans_format("log10",math_format(10^x)),minor_breaks=10^(seq(0,7, by=0.25)))+ theme_minimal()+labs(x="Dilution",y="% Bound")+ scale_color_brewer(type="Sample",palette="Set1")
尝试添加平滑线条时,使用geom_smooth(aes(linetype=X..bound))仅得到带阴影的拟合线,且报错:a continuous variable cannot be mapped to linetype。需求如下:
- 实现绘图线条的平滑
- 添加无背景色的S型最佳拟合线,且该线条能在图例中显示标签
附实验数据:
structure(list(Dilution = c(300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L), X..bound = c(52.74, 40.31, 30.63, 18.89, 7.57, 0.8, 0.01, 20.23, 11.29, 7.55, 3.24, 0.54, 0.12, 0.03, 53.27, 46.82, 38.17, 26.77, 11.59, 2.23, 0.07, 69.25, 63.55, 56.34, 40.95, 19.35, 2.4, 0.05, 75.8, 68.21, 62.82, 40.33, 11.73, 0.82, 0.04, 85.75, 82.82, 74.29, 46.63, 9.36, 0.24, 0.05, 71.65, 66.54, 56.63, 33.96, 6.33, 0.19, 0.03, 85.43, 86.49, 75.73, 51.62, 15.16, 1.05, 0.01, 92.44, 90.13, 85.92, 72.06, 30.08, 3.15, 0.12 ), Sample = c("1mer 0DA", "1mer 0DA", "1mer 0DA", "1mer 0DA", "1mer 0DA", "1mer 0DA", "1mer 0DA", "1mer 2DA", "1mer 2DA", "1mer 2DA", "1mer 2DA", "1mer 2DA", "1mer 2DA", "1mer 2DA", "1mer 3DA", "1mer 3DA", "1mer 3DA", "1mer 3DA", "1mer 3DA", "1mer 3DA", "1mer 3DA", "1mer 4DA", "1mer 4DA", "1mer 4DA", "1mer 4DA", "1mer 4DA", "1mer 4DA", "1mer 4DA", "5mer 0DA", "5mer 0DA", "5mer 0DA", "5mer 0DA", "5mer 0DA", "5mer 0DA", "5mer 0DA", "5mer 2DA", "5mer 2DA", "5mer 2DA", "5mer 2DA", "5mer 2DA", "5mer 2DA", "5mer 2DA", "5mer 4DA", "5mer 4DA", "5mer 4DA", "5mer 4DA", "5mer 4DA", "5mer 4DA", "5mer 4DA", "5mer 2DA GDG", "5mer 2DA GDG", "5mer 2DA GDG", "5mer 2DA GDG", "5mer 2DA GDG", "5mer 2DA GDG", "5mer 2DA GDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG" )), class = "data.frame", row.names = c(NA, -63L))
错误原因分析
geom_smooth(aes(linetype=X..bound))报错的核心原因是:ggplot2中,线型(linetype)仅支持映射离散分类变量,而X..bound是连续的百分比数值,因此触发该错误。
解决方案
1. 添加全局S型拟合线(无阴影+图例显示)
使用逻辑回归模型拟合S型曲线,设置se=FALSE去掉置信区间阴影,通过给linetype指定固定字符串来生成图例标签:
library(ggplot2) library(ggpubr) library(scales) ggline(Titration.Aug.9, x="Dilution", y="X..bound", color="Sample") + scale_x_continuous(trans="log10", labels=trans_format("log10", math_format(10^x)), minor_breaks=10^(seq(0,7, by=0.25))) + theme_minimal() + labs(x="稀释度", y="结合率(%)") + scale_color_brewer(palette="Set1") + # 添加S型拟合线:quasibinomial适配比例数据,se=FALSE去掉阴影 geom_smooth(aes(linetype="S型拟合线"), method="glm", family=quasibinomial(link="logit"), se=FALSE, color="black", fullrange=TRUE) + # 配置线型图例 scale_linetype_discrete(name="", labels="S型拟合线")
2. 按样本分组拟合S型线(每个样本一条拟合线)
如果需要每个样本单独生成拟合线,只需将linetype映射到Sample变量:
ggline(Titration.Aug.9, x="Dilution", y="X..bound", color="Sample") + scale_x_continuous(trans="log10", labels=trans_format("log10", math_format(10^x)), minor_breaks=10^(seq(0,7, by=0.25))) + theme_minimal() + labs(x="稀释度", y="结合率(%)") + scale_color_brewer(palette="Set1") + # 按样本分组拟合,se=FALSE去掉阴影 geom_smooth(aes(linetype=Sample), method="glm", family=quasibinomial(link="logit"), se=FALSE, fullrange=TRUE) + # 调整图例名称 scale_linetype_discrete(name="样本")
3. 专业四参数逻辑回归拟合(推荐用于剂量反应实验)
对于滴定类实验,四参数逻辑回归是更精准的S型曲线拟合模型,需要使用drc包:
library(drc) ggline(Titration.Aug.9, x="Dilution", y="X..bound", color="Sample") + scale_x_continuous(trans="log10", labels=trans_format("log10", math_format(10^x)), minor_breaks=10^(seq(0,7, by=0.25))) + theme_minimal() + labs(x="稀释度", y="结合率(%)") + scale_color_brewer(palette="Set1") + # 调用drc包的四参数模型 stat_smooth(aes(linetype="四参数拟合线"), method = "drm", method.args = list(fct = LL.4(names = c("斜率", "下限", "上限", "半效浓度"))), se = FALSE, color = "black", fullrange = TRUE) + scale_linetype_discrete(name="", labels="四参数S型拟合线")
内容的提问来源于stack exchange,提问作者Regan
相关产品推荐
相关产品推荐

