Isso é peculiar definitivamente. Como um primeiro pensamento: ao fazer a comparação de modelos em que os modelos estão tendo diferentes estruturas de efeitos fixos ( m2e, m3por exemplo), é melhor para nós o pois "mudará" . (Ele será multiplicado por , onde ) Isso é interessante porque funciona usando o que me faz acreditar que pode não ser um bug. Parece quase que aplica "boas práticas".y k k X = 0MLREMLykkX=0method="ML"
Dito isto, vamos olhar sob o capô:
methods(AIC)
getAnywhere('AIC.default')
A single object matching ‘AIC.default’ was found
It was found in the following places
registered S3 method for AIC from namespace stats
namespace:stats with value
function (object, ..., k = 2)
{
ll <- if ("stats4" %in% loadedNamespaces())
stats4:::logLik
else logLik
if (!missing(...)) {
lls <- lapply(list(object, ...), ll)
vals <- sapply(lls, function(el) {
no <- attr(el, "nobs") #THIS IS THE ISSUE!
c(as.numeric(el), attr(el, "df"), if (is.null(no)) NA_integer_ else no)
})
val <- data.frame(df = vals[2L, ], ll = vals[1L, ])
nos <- na.omit(vals[3L, ])
if (length(nos) && any(nos != nos[1L]))
warning("models are not all fitted to the same number of observations")
val <- data.frame(df = val$df, AIC = -2 * val$ll + k * val$df)
Call <- match.call()
Call$k <- NULL
row.names(val) <- as.character(Call[-1L])
val
}
else {
lls <- ll(object)
-2 * as.numeric(lls) + k * attr(lls, "df")
}
}
onde no seu caso você pode ver que:
lls <- lapply(list(m2,m3), stats4::logLik)
attr(lls[[1]], "nobs")
#[1] 500
attr(lls[[2]], "nobs")
#[1] 498
e obviamente logLikestá fazendo algo (talvez?) inesperado ...? não, na verdade, se você olhar para a documentação de logLik, ?logLikverá que está explicitamente declarado:
There may be other attributes depending on the method used: see
the appropriate documentation. One that is used by several
methods is ‘"nobs"’, the number of observations used in estimation
(after the restrictions if ‘REML = TRUE’)
o que nos leva de volta ao nosso ponto original, você deveria estar usando ML.
Para usar um ditado comum no CS: "Não é um bug; é um recurso (real)!"
EDIT : (Apenas para endereçar seu comentário :) Suponha que você se enquadre em outro modelo usando lmereste tempo:
m3lmer <- lmer(y ~ x + 1|cat)
e você faz o seguinte:
lls <- lapply(list(m2,m3, m3lmer), stats4::logLik)
attr(lls[[3]], "nobs")
#[1] 500
attr(lls[[2]], "nobs")
#[1] 498
O que parece ser uma clara discrepância entre os dois, mas realmente não é como Gavin explicou. Apenas para afirmar o óbvio:
attr( logLik(lme(y ~ x, random = ~ 1|cat, na.action = na.omit, method="ML")),
"nobs")
#[1] 500
Há uma boa razão pela qual isso acontece em termos de metodologia, eu acho. lmetenta entender a regressão LME para você enquanto, lmerao fazer comparações de modelos, ela volta imediatamente aos resultados de ML. Eu acho que não há bugs sobre esse assunto lmee lmerapenas diferentes razões por trás de cada pacote.
Veja também o comentário de Gavin Simposon sobre uma explicação mais perspicaz do que aconteceu anova()(a mesma coisa acontece praticamente com AIC)