如何在lattice中正确绘制指数、双曲及反双曲模型曲线?
修正Lattice多模型曲线绘制问题
问题诊断
- 第一个面板无输出:
setosa物种的Petal.Length与Petal.Width呈正相关,但你使用的指数模型y = a*exp(-b*x)是递减趋势,初始值设置不合理导致nls拟合失败,直接中断了第一个面板的绘制流程。 - 模型定义偏差:
- 反双曲模型:你写的
y = a/x不符合常见反双曲模型形式,建议采用y = a + b/x这类更合理的结构。 - 双曲模型:你写的
y = a*x是线性模型,并非双曲模型,常见双曲形式为y = (a*x)/(b + x)(米氏方程类型)。
- 反双曲模型:你写的
- 曲线绘制逻辑问题:直接用原数据的
x值预测得到的是离散点连接的折线,而非平滑曲线;同时未处理模型拟合失败的异常情况,一旦某模型拟合出错,整个面板都会停止输出。
修正后的代码
library(lattice) xyplot( Petal.Width ~ Petal.Length | Species, data = iris, panel = function(x, y, ...) { # 绘制基础散点 panel.xyplot(x, y, ...) # 生成连续x序列用于预测,保证曲线平滑 x_seq <- seq(min(x), max(x), length.out = 100) new_data <- data.frame(x = x_seq) # 线性模型 mod1 <- lm(y ~ x) panel.abline(mod1, col = '#0080ff') # 二次多项式模型 mod2 <- lm(y ~ poly(x, 2)) pred2 <- predict(mod2, newdata = new_data) panel.lines(x_seq, pred2, col = 'purple', lwd = 2) # 三次多项式模型 mod3 <- lm(y ~ poly(x, 3)) pred3 <- predict(mod3, newdata = new_data) panel.lines(x_seq, pred3, col = '#ff00ff', lwd = 2) # 指数模型(调整公式为递增形式,适配正相关数据) mod4 <- tryCatch( nls(y ~ a * exp(b * x), start = list(a = 0.1, b = 0.5), data = data.frame(x, y)), error = function(e) NULL ) if (!is.null(mod4)) { pred4 <- predict(mod4, newdata = new_data) panel.lines(x_seq, pred4, col = "red", lwd = 2) } # 反双曲模型(y = a + b/x) mod5 <- tryCatch( nls(y ~ a + b/x, start = list(a = 0.1, b = 0.5), data = data.frame(x, y)), error = function(e) NULL ) if (!is.null(mod5)) { pred5 <- predict(mod5, newdata = new_data) panel.lines(x_seq, pred5, col = "green", lwd = 2) } # 双曲模型(米氏方程形式:y = (a*x)/(b + x)) mod6 <- tryCatch( nls(y ~ (a*x)/(b + x), start = list(a = 2, b = 1), data = data.frame(x, y)), error = function(e) NULL ) if (!is.null(mod6)) { pred6 <- predict(mod6, newdata = new_data) panel.lines(x_seq, pred6, col = "orange", lwd = 2) } } )
修改说明
- 用
panel.lines配合连续x序列替代panel.curve,确保绘制出平滑曲线; - 给所有
nls模型添加tryCatch捕获拟合失败的异常,避免单个模型出错导致整个面板无输出; - 调整指数模型的公式为递增形式
a*exp(b*x),并适配初始值,解决setosa物种的拟合问题; - 修正反双曲和双曲模型的公式,符合行业通用的模型结构;
- 生成连续x序列
x_seq,保证模型预测结果能形成平滑曲线。
内容的提问来源于stack exchange,提问作者12666727b9
相关产品推荐
相关产品推荐

