如何在nlsList中实现algorithm='port'调用与参数k下限控制?
解决nlsList无法设置参数约束的问题
问题背景
使用nlsList拟合分组非线性模型时,需要限制参数k不低于0.1,参照nls()的用法添加了algorithm="port"和lower=c(k = 0.1, Max =-Inf, Lag = -Inf)参数,却报错提示这两个参数未被nlsList支持。
解决方案
方法1:手动分组调用nls(带约束)
nlsList本质是对每个分组数据调用nls(),但它没有暴露algorithm和参数约束相关参数。可以手动循环分组数据,直接调用带约束的nls(),再将结果转换为nlsList对象:
library(nlme) library(tidyr) # 数据准备 dat <- read.table(text="time gluc starch solka 1 6.32 7.51 1.95 2 20.11 25.49 6.43 3 36.03 47.53 10.39 6 107.52 166.31 27.01 12 259.28 305.19 113.72 24 283.40 342.56 251.14 48 297.55 353.66 314.22", header = TRUE) long <- pivot_longer(dat, -1, values_to = "y") long$name <- factor(long$name) st0 <- list(Max = 200, k = 0.1, Lag = 0.5) # 对每个分组单独拟合带约束的nls模型 fit_list <- lapply(split(long, long$name), function(df) { nls(y ~ (time > Lag) * Max * (1-exp(-k * (time - Lag))), data = df, algorithm = "port", lower = c(k = 0.1, Max = -Inf, Lag = -Inf), start = st0) }) # 将结果转换为nlsList对象(保持和原用法一致的输出结构) fit_nlslist <- as.nlsList(fit_list)
方法2:改用nlme函数(支持参数约束的混合效应框架)
如果可以接受混合效应模型的框架,nlme包的nlme()函数支持设置参数约束,同时也能实现分组拟合:
# 使用nlme拟合带参数约束的模型 fit_nlme <- nlme(y ~ (time > Lag) * Max * (1-exp(-k * (time - Lag))), data = long, fixed = Max + k + Lag ~ 1, # 固定效应设定 random = Max + k + Lag ~ 1 | name, # 分组随机效应 start = c(Max = 200, k = 0.1, Lag = 0.5), lower = c(k = 0.1), # 仅限制k的下限 algorithm = "port") # 提取各分组的拟合系数 coef(fit_nlme)
原因说明
nlsList的函数参数中并未包含algorithm和lower,它内部默认调用无约束的nls()算法,因此无法直接设置参数约束。上述两种方法分别通过手动实现分组拟合,或切换到支持约束的混合效应模型框架,解决参数限制的需求。
内容的提问来源于stack exchange,提问作者hnguyen
相关产品推荐
相关产品推荐

