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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:45:06