R语言使用nlme包nlsList分组拟合非线性回归报错如何解决
分组非线性回归报错问题解决方案
错误原因
- 变量名大小写不匹配:数据集内响应变量名为
Exp_flux(小写f),nlsList公式中写为Exp_Flux(大写F),R大小写敏感导致变量识别失败,是出现空返回/报错的核心原因。 - 示例数据构造代码存在语法错误:
Exp_flux <- 3.5*exp((Ts-10)/10缺少右括号,会导致数据集生成失败。 - 初始值设置适配性不足:当前给定的
q=2与模拟数据的真实参数(q≈2.718)存在偏差,若实际数据波动更大,不合适的初始值会导致部分分组拟合不收敛,触发nlsList返回异常。
修正后的nlsList实现代码
# 加载依赖包 library(nlme) # 修正后的数据集构造代码 Date <- as.POSIXct(c("2021-05-25","2021-05-20", "2021-05-21","2021-05-22", "2021-05-23","2021-05-24" ,"2021-05-25","2021-05-20", "2021-05-21","2021-05-22", "2021-05-23","2021-05-24" ,"2021-05-25","2021-05-20", "2021-05-21","2021-05-22", "2021-05-23","2021-05-24" ,"2021-05-25","2021-05-20", "2021-05-21","2021-05-22", "2021-05-23","2021-05-24" ,"2021-05-25")) Ts <- rnorm(25, mean=10, sd=0.5) # 补全右括号 Exp_flux <- 3.5*exp((Ts-10)/10) Collar <- as.factor(c("t1","t2","t3","t4","t5","t1","t2","t3","t4","t5","t1","t2","t3","t4", "t5","t1","t2","t3","t4","t5","t1","t2","t3","t4","t5")) df <- data.frame(Date,Collar,Ts,Exp_flux) # 修正变量名、调整初始值后的nlsList代码 fit.collars <- nlsList(Exp_flux ~ SRref*q^((Ts-10)/10)| Collar, data = df, start = list(SRref = 3.5, q = exp(1)), na.action = na.omit) # 正常输出所有分组的拟合结果 summary(fit.collars)
更灵活的替代实现方案
如果存在部分分组拟合不收敛的情况,可使用嵌套分组+批量拟合的方案,该方案支持自动捕获拟合失败的分组,不会中断整体运行:
library(tidyverse) library(broom) df_fit <- df %>% # 按分组列嵌套数据 group_by(Collar) %>% nest() %>% mutate( # 逐组拟合,错误返回NA不中断运行 fit = map(data, ~tryCatch( nls(Exp_flux ~ SRref*q^((Ts-10)/10), data = .x, start = list(SRref=3.5, q=exp(1))), error = function(e) NA )), # 提取拟合参数 params = map(fit, ~if(all(is.na(.x))) NA else tidy(.x)), # 提取拟合统计量 fit_stats = map(fit, ~if(all(is.na(.x))) NA else glance(.x)) ) # 导出所有分组的拟合参数 df_fit %>% unnest(params) # 导出所有分组的拟合统计量 df_fit %>% unnest(fit_stats)
内容的提问来源于stack exchange,提问作者Torben Callesen
相关产品推荐
相关产品推荐

