I know the web is plastered with questions (and answers) about the \'initial value in vmmim is not finite\'
error when trying to fit parameters for an mle2
There are a few things to try here. First look at the data (always a good idea):
library("ggplot2"); theme_set(theme_bw())
ggplot(d,aes(SST_1YR,DML)) + geom_point()+
geom_smooth(method="glm",family=Gamma(link="identity"))+
geom_smooth(method="lm",colour="red",fill="red")
Note that in this case the Gamma regression looks almost identical to a regular linear regression (i.e. the shape parameter is large). Also, the distribution of the x values is far from the origin -- this may lead to numeric problems.
library("bbmle")
m <- mle2(DML~dgamma(scale=(a+b*SST_1YR)/sh, shape=sh),
start=list(a=170, b=-7.4, sh=10), data=d)
confint(m)
Confirms the problem:
## 2.5 % 97.5 %
## a 132.05952 203.192159
## b NA -4.407289
## sh 6.83566 13.933383
I thought that setting parscale
could help, but it appears to make the problem worse rather than better:
m2 <- update(m,control=list(parscale=c(a=170,b=8,sh=10)))
confint(m2)
## 2.5 % 97.5 %
## a NA 203.153230
## b NA -4.407281
## sh 6.835659 13.933383
Does centering the predictor variable help? scale(x,scale=FALSE)
centers but doesn't scale x
... (using SST_1YR-mean(SST_1YR)
might be clearer, that way we wouldn't have three scale
s floating around in the expression ...
m3 <- mle2(DML~dgamma(scale=(a+b*scale(SST_1YR,scale=FALSE))/sh, shape=sh),
start=list(a=170, b=-7.4, sh=10), data=d)
confint(m3)
## 2.5 % 97.5 %
## a 56.462610 66.754118
## b -9.421521 -4.407262
## sh 6.835662 13.933384
Looks good, although it would be a little tricky to get the intercept terms back to the original scale (although we could just take them from the previous, uncentered fit).
It turns out you can also fit this model via
glm(DML~SST_1YR,family=Gamma(link="identity"),data=d)
although confint()
again fails rather mysteriously (Error in y/mu: non-conformable arrays
).
Some other things that I tried that didn't work particularly well (included here only for completeness):
mle2(DML~dgamma(scale=pmin((a+b*SST_1YR)/sh,1e-5),
shape=sh),
start=list(a=170, b=-7.4, sh=10), data=d)
dgamma
to return bad likelihoods rather than NA
when x<0
:dgamma_pen <- function(x,...,log=FALSE) {
r <- if (x<0) (-100) else dgamma(x,...,log=TRUE)
if (log) r else exp(r)
}
m4 <- mle2(DML~dgamma_pen(scale=pmin((a+b*SST_1YR)/sh,1e-5),
shape=sh),
start=list(a=170, b=-7.4, sh=10), data=d)