以下是一些考古工作的结果,它解释了在glm
函数深处发生了什么:
通过调试(使用debug("glm")
)并逐步执行函数,可以发现它在以下调用处失败:
if (length(offset) && attr(mt, "intercept") > 0L) {
fit$null.deviance <- eval(call(if (is.function(method)) "method" else method,
x = X[, "(Intercept)", drop = FALSE], y = Y, weights = weights,
offset = offset, family = family, control = control,
intercept = TRUE))$deviance
}
这是计算模型的零偏差的尝试。仅在存在截距项和偏移项时进行评估(我不确定为什么;可能是由于上一次调用 glm
计算的默认零偏差在这种情况下是错误的,必须重新计算?)。它调用 glm.fit
(method
的默认值),但是没有启动值,因为对于仅有截距的模型来说,通常不需要启动值。
现在正在 glm.fit
内部进行调试以查看发生了什么:我们(在调用 family 函数 gaussian()
时)得到:
if (is.null(etastart) && is.null(start) && is.null(mustart) &&
((family$link == "inverse" && any(y == 0)) || (family$link ==
"log" && any(y <= 0))))
stop("cannot find valid starting values: please specify some")
我们可以看到,由于起始值未经过传递,使用了对数链接,并且有一些y
值等于零,拟合失败了。因此,仅当同时指定偏移量和截距、使用对数链接并且响应值为零时,才会发生这种情况。
如果您运行dump("glm",file="glmtemp.R")
,请添加以下行。
start = start[1], etastart = etastart[1], mustart = mustart[1],
对于适合零偏差(即上面显示的那个)的调用,以及source("glmtemp.R")
,它似乎可以正常工作...我认为这应该是一个合理的通用解决方案。如果有人想在R开发列表中提出这个问题,请随意。
glm(y〜1 + offset(junk))
,一切正常。我认为您的数据集非常小,并且具有一些不太可能的偏移量,因此glm无法找到适合的拟合。” - Carl Witthofty
值中取对数0。尝试使用非零正数的y
,它将起作用,并且不需要start
。 - James