I want to define my own density function to be used in the formula call to mle2
from R
's bbmle
package. The parameters of the model are estimated but I cannot apply functions like residuals
or predict
on the returned mle2
object.
This is an example in which I define a function for a simple Poisson model.
library(bbmle)
set.seed(1)
hpoisson <- rpois(1000, 10)
myf <- function(x, lambda, log = FALSE) {
pmf <- (lambda^x)*exp(-lambda)/factorial(x)
if (log)
log(pmf)
else
pmf
}
myfit <- mle2(hpoisson ~ myf(lambda), start = list(lambda=9), data=data.frame(hpoisson))
residuals(myfit)
In myfit
, the lambda is estimated correctly but when I call residuals on myfit
, I get an error which says:
Error in myf(9.77598906811668) :
argument "lambda" is missing, with no default
On the other hand, if I simply fit the model as follows using R
's built-in dpois
function, the residuals are computed:
myfit <- mle2(hpoisson ~ dpois(lambda), start = list(lambda=9), data=data.frame(hpoisson))
residuals(myfit)
Could anyone please tell me what I am doing wrong in the function definition of myf
?
Thanks
It's not very clearly explained in the documents, but there are a few prerequisites for using custom density functions:
- the function's name must start with
d
, must have first argumentx
, and must have a named argumentlog
. (Thelog
argument has to do something sensible: in particular,mle2
will call the function withlog=TRUE
, and the function had better return the log-likelihood!) In general, although it's not required, it's more numerically sensible to compute the log-likelihood directly and then exponentiate iflog=FALSE
, rather than computing the likelihood and logging it iflog=TRUE
(there are cases, such as zero-inflated models, where this isn't really feasible). For example, compare mydmyf()
definition with themyf()
definition in the OP's code ... - in order to use additional methods such as
predict
you have to define an additional function whose name starts withs
; it returns a list of moments, summary statistics, etc. for a specified parameter -- see example below, which is copied frombbmle::spois
.
library("bbmle")
set.seed(1)
hpoisson <- rpois(1000, 10)
dmyf <- function(x, lambda, log = FALSE) {
logpmf <- x*log(lambda)-lambda-lfactorial(x)
if (log) return(logpmf) else return(exp(logpmf))
}
smyf <- function(lambda) {
list(title = "modified Poisson",
lambda = lambda, mean = lambda,
median = qpois(0.5, lambda),
mode = NA, variance = lambda, sd = sqrt(lambda))
}
myfit <- mle2(hpoisson ~ dmyf(lambda),
start = list(lambda=9), data=data.frame(hpoisson))
residuals(myfit)
Not really an answer, but more help needed on this:
I used this to try to make a "custom" beta-binomial function to mimic the one in the first bit of the bbmle vignette.
set.seed(1001)
x1 <- rbetabinom(n=1000, prob=0.1, size=50, theta=10)
dmybetabinom <- function(x, N, theta, p, log=FALSE) {
(choose(N,x)*beta(N-x+theta*(1-p),x+theta*p))/beta(theta*(1-p),theta*p)
}
The function works like dbetabinom:
dbetabinom(0:9,size=9,theta=4, prob=0.5)
[1] 0.04545455 0.08181818 0.10909091 0.12727273 0.13636364 0.13636364 0.12727273 0.10909091
[9] 0.08181818 0.04545455
dmybetabinom(0:9,N=9,theta=4, p=0.5)
[1] 0.04545455 0.08181818 0.10909091 0.12727273 0.13636364 0.13636364 0.12727273 0.10909091
[9] 0.08181818 0.04545455
But when I try to use the mle2 function on it, I am met with this error:
m0fa <- mle2(x1~dmybetabinom( N=50, theta, p), start=list(p=0.2, theta=9), data=data.frame(x1) )`
Error in optim(par = c(0.2, 9), fn = function (p) : non-finite finite-difference value [1] `
来源:https://stackoverflow.com/questions/28384164/error-with-custom-density-function-definition-for-mle2-formula-call