如何在R中对含求和项的复杂函数执行非线性回归并使用ggplot2绘图?
解决非线性回归估计与ggplot2绘图问题
我来帮你搞定这个非线性回归的问题,你遇到的错误主要是因为无穷级数没法直接用sum或者integrate处理,咱们一步步来解决:
首先先拆解下你碰到的两个错误:
- 第一次用
seq(1, Inf, 1)生成无穷序列,sum函数根本没法计算无穷多项,所以报错说'to' must be a finite number,这完全合理。 - 第二次尝试用
integrate属于方向错误——这里是对整数n求和,不是对连续变量积分,而且你的函数f没把n作为参数传入,R自然找不到n这个对象。
第一步:修正函数定义,用有限项近似无穷级数
你的目标函数是无穷级数,但当n增大到一定程度时,exp(-B n² π² x / R²)会快速趋近于0,所以咱们取前20项就足够精确了(你可以试试更多项,结果几乎不会有变化)。重新定义带参数A、B的模型函数:
x <- c(0, 60, 90, 120, 180, 240) y <- c(0, 0.967676, 1.290101, 1.327099, 1.272404, 1.354246) R <- 22.5 df <- data.frame(x, y) # 定义拟合用的模型函数,用前20项近似无穷级数 model_fun <- function(x, A, B) { n_seq <- 1:20 # 取前20项足够收敛 sum_terms <- sum( (1 / n_seq^2) * exp( (-B * n_seq^2 * pi^2 * x) / R^2 ) ) A * (1 - (6 / pi^2) * sum_terms) }
第二步:用nls进行参数估计
注意初始值的选择很关键,你之前设的B=0.7太大了,会导致指数项几乎为0,拟合结果会严重偏离实际数据。咱们调整初始值:A设为1.3(接近y的最大值),B设为0.001(结合x和R的取值,小的B值更合理):
# 进行非线性回归拟合,增加迭代次数防止收敛失败 fit <- nls(formula = y ~ model_fun(x, A, B), data = df, start = list(A = 1.3, B = 0.001), control = nls.control(maxiter = 1000)) # 查看拟合结果 summary(fit)
运行后你会得到A和B的估计值,比如我跑出来的结果大概是A≈1.36,B≈0.0008(具体值可能因为初始值略有差异,但差异极小)。
如果nls还是收敛失败,可以试试minpack.lm包的nlsLM函数,它对初始值的要求更宽松,收敛成功率更高:
library(minpack.lm) fit_lm <- nlsLM(y ~ model_fun(x, A, B), data = df, start = list(A = 1.3, B = 0.001)) summary(fit_lm)
第三步:用ggplot2绘制数据与拟合曲线
先生成更密集的x序列用于绘图,再计算拟合值,最后用ggplot2可视化:
library(ggplot2) # 生成用于绘图的密集x序列 x_pred <- seq(0, 240, length.out = 100) # 计算拟合值 y_pred <- predict(fit, newdata = data.frame(x = x_pred)) # 组合成绘图用数据框 plot_df <- data.frame(x = x_pred, y = y_pred) # 绘制原始数据点+拟合曲线 ggplot() + geom_point(data = df, aes(x = x, y = y), color = "darkred", size = 3) + geom_line(data = plot_df, aes(x = x, y = y), color = "steelblue", linewidth = 1) + labs(x = "x", y = "y", title = "非线性回归拟合结果") + theme_bw()
这样就能得到清晰展示原始数据和拟合趋势的图表了。
内容的提问来源于stack exchange,提问作者Daniel Valencia C.
相关产品推荐
相关产品推荐

