当我在nlme中使用数据时,我在第一次尝试时从未成功,在nlme(fit.model)
之后我习惯于看到如下内容:
Error in nlme.formula(model = mass ~ SSbgf(day, w.max, t.e, t.m), random = list( :
step halving factor reduced below minimum in PNLS step
Error in MEestimate(nlmeSt, grpShrunk) :
Singularity in backsolve at level 0, block 1
所以我回去了
1)更改x轴的单位(例如,从几年到几天,或几天到成长度日)。
2)在我的数据集中进行x = 0,y = 0测量
3)添加random=pdDiag()
4)混淆什么是随机的和什么是固定的
5)切断我的数据集并尝试在不同时间安装不同的部分
6)实现非常简单的拟合,然后使用update
使模型正确
最终似乎有些事情可行。还有其他人有什么要添加到此列表中吗?什么可以帮助您获取数据?
我意识到这个问题可能会被关闭,但是如果有任何关于如何将其重新命名为SO可以接受的建议,我将不胜感激。
以下是我尝试了其中一些内容的示例,但到目前为止尚未取得成功:
数据:https://www.dropbox.com/s/4inldx7617fip01/proots.csv。这已经只是整个集合的一部分。
代码:
roots<-read.table("proots.csv", header = TRUE)
#roots$day[roots$year == 2007] <- 0 #when I use a dataset with time=0, mass=0
roots$day[roots$year == 2008] <- 153
roots$day[roots$year == 2009] <- 518
roots$day[roots$year == 2010] <- 883
roots$day[roots$year == 2011] <- 1248
roots$day[roots$year == 2012] <- 1613
roots$day[roots$year == 2013] <- 1978
#or bigger time steps
roots$time[roots$year == 2008] <- 1
roots$time[roots$year == 2009] <- 2
roots$time[roots$year == 2010] <- 3
roots$time[roots$year == 2011] <- 4
roots$time[roots$year == 2012] <- 5
roots$time[roots$year == 2013] <- 6
roots$EU<- with(roots, factor(plot):factor(depth)) #EU is "experimental unit"
rootsG<-groupedData(mass ~ day | EU, data=roots)
#I will post the SSbgf function below -- run it first
fit.beta <- nlsList(mass ~ SSbgf(day, w.max, t.e, t.m), data = rootsG)
fit.nlme.bgf<-nlme(fit.beta)
fit.nlme.bgf<-nlme(fit.beta, random=list(w.max + t.e + t.m ~1))
fit.nlme.bgf<-nlme(fit.beta, random=list(w.max ~ 1))
fit.nlme.bgf<-nlme(fit.beta, random=pdDiag(w.max ~1))
fit.nlme.bgf<-nlme(fit.beta, random=pdDiag(w.max + t.e + t.m ~1))
fit.nlme.bgf<-nlme(fit.beta, random=list(t.m ~1))
fit.nlme.bgf<-nlme(fit.beta, random=list(t.e ~1))
fit.nlme.bgf<-nlme(fit.beta, random=pdSymm(w.max ~1))
fit.nlme.bgf<-nlme(fit.beta, random=pdDiag(w.max ~1))
这是曲线的函数(SSbgf):
bgfInit <- function(mCall, LHS, data){
xy <- sortedXyData(mCall[["time"]], LHS, data)
if(nrow(xy) < 4){
stop("Too few distinct input values to fit a bgf")
}
w.max <- max(xy[,"y"])
t.e <- NLSstClosestX(xy, w.max)
t.m <- NLSstClosestX(xy, w.max/2)
value <- c(w.max, t.e, t.m)
names(value) <- mCall[c("w.max","t.e","t.m")]
value
}
bgf <- function(time, w.max, t.e, t.m){
.expr1 <- t.e / (t.e - t.m)
.expr2 <- (time/t.e)^.expr1
.expr3 <- (1 + (t.e - time)/(t.e - t.m))
.value <- w.max * .expr3 * .expr2
## Derivative with respect to t.e
.exp1 <- ((time/t.e)^(t.e/(t.e - t.m))) * ((t.e-time)/(t.e-t.m) + 1)
.exp2 <- (log(time/t.e)*((1/(t.e-t.m) - (t.e/(t.e-t.m)^2) - (1/(t.e - t.m)))))*w.max
.exp3 <- (time/t.e)^(t.e/(t.e-t.m))
.exp4 <- w.max * ((1/(t.e-t.m)) - ((t.e - time)/(t.e-t.m)^2))
.exp5 <- .exp1 * .exp2 + .exp3 * .exp4
## Derivative with respect to t.m
.ex1 <- t.e * (time/t.e)^((t.e/(t.e - t.m))) * log(time/t.e) * ((t.e - time)/(t.e -
t.m) + 1) * w.max
.ex2 <- (t.e - time) * w.max * (time/t.e)^(t.e/(t.e-t.m))
.ex3 <- (t.e - t.m)^2
.ex4 <- .ex1 / .ex3 + .ex2 / .ex3
.actualArgs <- as.list(match.call()[c("w.max", "t.e", "t.m")])
## Gradient
if (all(unlist(lapply(.actualArgs, is.name)))) {
.grad <- array(0, c(length(.value), 3L), list(NULL, c("w.max",
"t.e", "t.m")))
.grad[, "w.max"] <- .expr3 * .expr2
.grad[, "t.e"] <- .exp5
.grad[, "t.m"] <- .ex4
dimnames(.grad) <- list(NULL, .actualArgs)
attr(.value, "gradient") <- .grad
}
.value
}
SSbgf <- selfStart(bgf, initial = bgfInit, c("w.max", "t.e", "t.m"))
答案 0 :(得分:5)
另一个技巧是增加pnls容差。
所需的代码是:
control = nlmeControl(pnlsTol = x, msVerbose = TRUE)
pnls容差的起始值是0.001,所以我喜欢从0.01或0.02开始。只需用您的号码替换x,就应该设置。