我有一个nls
fitting
任务,我想用R做。
我第一次尝试这样做here和@Roland指出
"重点是复杂的模型难以适应。更重要的是,数据支持模型的次数越少,直至变得不可能。如果你有非常好的起始值,你可能适合这个。"
我同意@Roland但如果excel
可以做到这一点,那么为什么R
无法做到呢?
基本上这种拟合可以用Excel的GRG非线性求解器完成,但是这个过程非常耗时,有时拟合并不好。 (因为现实中有很多数据)。
这是我的示例data.frame。我想让每个set
组适合下面提供的模型,
set.seed(12345)
set =rep(rep(c("1","2","3","4"),each=21),times=1)
time=rep(c(10,seq(100,900,100),seq(1000,10000,1000),20000),times=1)
value <- replicate(1,c(replicate(4,sort(10^runif(21,-6,-3),decreasing=FALSE))))
data_rep <- data.frame(time, value,set)
> head(data_rep)
# time value set
#1 10 1.007882e-06 1
#2 100 1.269423e-06 1
#3 200 2.864973e-06 1
#4 300 3.155843e-06 1
#5 400 3.442633e-06 1
#6 500 9.446831e-06 1
* * * *
我已在此处trouble-when-adding-3rd-fitting-parameter-in-nls
发布了一个问题基本上问题在于我想对分组数据进行拟合并根据拟合系数进行预测。
我使用了来自nlsLM
的{{1}}我收到了错误
根据@Roland,乍一看可能是模型错误或我的起始值不好。另一方面,我只能用两个拟合参数来拟合这个模型。当我想将nlsModel中的错误(公式,mf,start,wts,upper): 初始参数估计时的奇异梯度矩阵
library(minpack.lm)
参数添加到拟合函数时,就会出现问题。
在帖子trouble-when-adding-3rd-fitting-parameter-in-nls中关注@G。格洛腾迪克的建议,我在third
包中尝试了nlxb
,并将参数nlmrt
中的一个修改为d
并按照以下方式进行拟合;
d=32
拟合系数合理wolaa!但是这一次我意识到(@G.Grothendieck后来也指出)在formula = value~Ps*(1-exp(-2*f*time*exp(-d)))*1/(sqrt(2*pi*sigma))*exp(-(d-d_ave)^2/(2*sigma))*d_step
d_step <- 1
f <- 1e9
d <- 32
library(plyr)
library(nlmrt)
get.coefs <- function(data_rep) {
fit <- nlxb(formula ,
data = data_rep,
start=c(d_ave=44,sigma=12,Ps=0.5),
lower=c(d_ave=25,sigma=2,Ps=0.5),
upper=c(d_ave=60,sigma=15,Ps=1),
trace=TRUE)
}
fit <- dlply(data_rep, c("set"), .fun = get.coefs) # Fit data grouped by "set"
# > fit
# $`1`
# nlmrt class object: x
# residual sumsquares = 1.474e-07 on 21 observations
# after 12 Jacobian and 13 function evaluations
# name coeff SE tstat pval #gradient JSingval
# d_ave 42.0126 NA NA NA #-7.082e-15 0.001733
# sigma 12.8377 NA NA NA #2.408e-15 1.289e-19
# Ps 0.973223 NA NA NA #9.33e-15 3.37e-20
#
# $`2`
# nlmrt class object: x
# residual sumsquares = 6.2664e-08 on 21 observations
# after 12 Jacobian and 13 function evaluations
# name coeff SE tstat pval #gradient JSingval
# d_ave 42.246 NA NA NA #-7.269e-15 0.001428
# sigma 12.7429 NA NA NA #2.568e-15 3.098e-19
# Ps 0.981517 NA NA NA #9.211e-15 2.746e-20
#
# $`3`
# nlmrt class object: x
# residual sumsquares = 1.773e-07 on 21 observations
# after 12 Jacobian and 13 function evaluations
# name coeff SE tstat pval #gradient JSingval
# d_ave 41.968 NA NA NA #-6.438e-15 0.001798
# sigma 12.8561 NA NA NA #2.173e-15 2.414e-19
# Ps 0.972988 NA NA NA #8.534e-15 5.922e-20
# $`4`
# nlmrt class object: x
# residual sumsquares = 2.5219e-07 on 21 observations
# after 12 Jacobian and 13 function evaluations
# name coeff SE tstat pval #gradient JSingval
# d_ave 41.8532 NA NA NA #-4.454e-15 0.001976
# sigma 12.9045 NA NA NA #1.474e-15 3.443e-19
# Ps 0.974319 NA NA NA #5.987e-15 3.124e-20
# attr(,"split_type")
# [1] "data.frame"
# attr(,"split_labels")
# set
# 1 1
# 2 2
# 3 3
# 4 4
之后预测新值是不可能的(为什么=?我不知道!)
nlxb
::您可以在here
中找到predvals <- ldply(fit, .fun=predictvals, xvar="time", yvar="value",xrange=range(range)) # predict values
函数
UseMethod出错(&#34;预测&#34;): 没有适用的方法来预测&#39;应用于类&#34; nlmrt&#34;
的对象
没有!对于predictvals
类对象,我需要coef
或predict methods
。
跟随@G。格洛腾迪克的另一个建议
接下来,我尝试了"nlmrt"
的{{1}}。
因为在这篇文章中他说, can-we-make-prediction-with-nlxb-from-nlmrt-package
&#34;因为nlmrt包确实提供wrapnls
,它将运行nlmrt
然后wrapnls
以便生成nlmrt
对象,然后该对象就可以与所有nls
类方法一起使用。
来自同样"nls"
的套餐仍有问题,如下所示
我在第一次post之后放弃使用"nls"
,因为加载nlmrt
和plyr
会让我的问题变得更复杂。所以我会坚持使用plyr
并使用dplyr
函数。
dplyr
nlsModel中的错误(公式,mf,start,wts,upper): 初始参数估计时的奇异梯度矩阵
我回到了我开始犯这个错误的地方。 我想我尝试了所有我能做的事情,寻找相关的例子(虽然只有3个),阅读书籍并遵循建议。
答案 0 :(得分:2)
在nls2
之后使用nls2包中的nlxb
(假设为data_rep
,
来自问题的formula
,d_step
,f
和d
。为了使示例最小化,我们已经消除了dplyr,只显示了set == 2的计算。
library(nlmrt)
library(nls2)
data_rep2 <- subset(data_rep, set == 2)
fit.nlxb <- nlxb(formula , data = data_rep2,
start = c(d_ave = 44, sigma = 12, Ps = 0.5),
lower = c(d_ave = 25, sigma = 2, Ps = 0.5),
upper = c(d_ave = 60, sigma = 15, Ps = 1))
fit.nls <- nls2(formula, data = data_rep2, start = fit.nlxb$coefficients,
algorithm = "brute-force")
identical(fit.nlxb$coefficients, coef(fit.nls))
## [1] TRUE
fit.nls
是一个"nls"
类对象,其系数与fit.nlxb
相同,我们可以使用fitted()
和predict()
以及所有其他"nls"
方法就可以了。