ggplot拟合曲线上查找特定y值对应x值(求EC50)方法求助
解决思路
你的原有方法是基于原始离散点做线性插值,仅能对应geom_line()生成的折线场景。而geom_smooth()默认使用loess局部加权回归拟合平滑曲线,两者的函数关系不一致,自然会出现计算结果与平滑曲线数值不匹配的问题。
具体实现方案
方案1:匹配geom_smooth默认的loess拟合计算EC50
该方案得到的结果与你现有绘图的平滑曲线完全对应:
library(ggplot2) # 你的示例数据 Concentration <- seq(from = 0, to = 9, by=1) GSH <- c(100, 67.405, 47.78, 39.2325, 33.97, 28.435, 26.97, 24.5125, 23.5275, 21.565) df <- data.frame(Concentration, GSH) # 显式拟合和geom_smooth默认参数一致的loess模型 loess_mod <- loess(GSH ~ Concentration, data = df, span = 0.75) # 构建loess拟合的预测函数 predict_gsh <- function(c) { predict(loess_mod, newdata = data.frame(Concentration = c)) } # 搜索EC50取值 ec50_loess <- optimize(function(x) abs(predict_gsh(x) - 50), interval = range(df$Concentration))$minimum # 输出结果约为1.92,与平滑曲线交点完全匹配 ec50_loess
验证绘图代码:
pred_data <- data.frame(Concentration = seq(0,9,length.out = 100)) pred_data$GSH <- predict(loess_mod, newdata = pred_data) ggplot(df, aes(Concentration, GSH)) + geom_point() + geom_line(data = pred_data, color = "cornflowerblue", linewidth = 1) + geom_vline(xintercept = ec50_loess, color = "red", linetype = 2) + geom_hline(yintercept = 50, color = "red", linetype = 2)
方案2:使用标准剂量反应模型计算EC50(推荐多组比较场景)
毒理学领域计算EC50的通用方案是使用四参数逻辑斯蒂(4PL)模型,结果稳定性和生物学解释性优于loess局部拟合,更适合多组数据对比:
# 安装依赖包 # install.packages("drc") library(drc) # 拟合4PL剂量反应模型 drc_mod <- drm(GSH ~ Concentration, data = df, fct = LL.4(names = c("斜率", "下限", "上限", "EC50"))) # 直接提取EC50结果,约为1.81 ec50_4pl <- summary(drc_mod)$coefficients["EC50:(Intercept)", "Estimate"] ec50_4pl
内容的提问来源于stack exchange,提问作者RBPawesome
相关产品推荐
相关产品推荐

