Вот результаты некоторой археологии, которая объясняет, что происходит, глубоко внутри функции 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
, чтобы увидеть, что происходит: мы попадаем на
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, не стесняйтесь.