我有一个数据集,我想按组应用非线性最小二乘法。这是我上一个问题的延续: NLS Function - Number of Iterations Exceeds max
数据集如下:
df
x y GRP
0 0 1
426 9.28 1
853 18.5 1
1279 27.8 1
1705 37.0 1
2131 46.2 1
0 0 2
450 7.28 2
800 16.5 2
1300 30.0 2
2000 40.0 2
2200 48.0 2
如果我要和一个小组一起做,那就是这样:
df1<-filter(df, GRP==1)
a.start <- max(df1$y)
b.start <- 1e-06
control1 <- nls.control(maxiter= 10000,tol=1e-02, warnOnly=TRUE)
nl.reg <- nls(y ~ a * (1-exp(-b * x)),data=df1,start=
list(a=a.start,b=b.start),
control= control1)
coef(nl.reg)[1]
coef(nl.reg)[2]
> coef(nl.reg)[1]
a
5599.075
> coef(nl.reg)[2]
b
3.891744e-06
然后,我将对GRP2执行相同的操作。我希望最终输出看起来像这样:
x y GRP a b
0 0 1 5599.075 3.891744e-06
426 9.28 1 5599.075 3.891744e-06
853 18.5 1 5599.075 3.891744e-06
1279 27.8 1 5599.075 3.891744e-06
1705 37.0 1 5599.075 3.891744e-06
2131 46.2 1 5599.075 3.891744e-06
0 0 2 New Value for a GRP2 New Value for b GRP2
450 7.28 2 New Value for a GRP2 New Value for b GRP2
800 16.5 2 New Value for a GRP2 New Value for b GRP2
1300 30.0 2 New Value for a GRP2 New Value for b GRP2
2000 40.0 2 New Value for a GRP2 New Value for b GRP2
2200 48.0 2 New Value for a GRP2 New Value for b GRP2
理想情况下,我认为dplyr是最好的方法,但我不知道该怎么做。我认为这可能是这样的:
control1 <- nls.control(maxiter= 10000,tol=1e-02, warnOnly=TRUE)
b.start <- 1e-06
df %>%
group_by(GRP) %>%
do(nlsfit = nls( form = y ~ a * (1-exp(-b * x)), data=.,
start= list( a=max(.$y), b=b.start),
control= control1) ) %>%
list(a = coef(nlsfit)[1], b = coef(nlsfit)[2])
错误:
in nlsModel(formula, mf, start, wts) :
singular gradient matrix at initial parameter estimates
虽然不太确定如何执行此操作,但任何帮助都将非常有用。谢谢!
答案 0 :(得分:1)
最初尝试使用nls
范式时,我最初得到的错误消息与重新使用tidyverse
时遇到的错误消息相同(例如:在lapply-split-function
中找不到对象'y'),并且去搜索:“ [r]在函数内使用nls”。我已经将attach
的原始用法更改为list2env
:
sapply( split( df , df$GRP), function(d){ dat <- list2env(d)
nlsfit <- nls( form = y ~ a * (1-exp(-b * x)), data=dat, start= list( a=max(y), b=b.start),
control= control1)
list(a = coef(nlsfit)[1], b = coef(nlsfit)[2])} )
#---
1 2
a 14.51827 441.5489
b 2.139378e-06 -6.775562e-06
您还会收到预期的警告。这些可以用suppressWarnings( ... )
建议之一是使用attach
。然后我极度不情愿地这样做了,因为我经常警告新手不要使用attach
。但是,这似乎在迫使当地环境的建设。我更喜欢list2env作为满足nls的机制。 nls
的代码顶部使我做出了选择:
if (!is.list(data) && !is.environment(data))
stop("'data' must be a list or an environment")