Wie übergebe ich eine benannte Liste an das Punktargument (`…`) einer Funktion (speziell `anova`) in R? (Alternativen zu `do.call`)
Ich habe eine Liste gemischter Modelle, deren Ausgabe lme4::lmer
ich übergeben möchte, anova
die die Form hat anova(object, ...)
, also tue ich es
models_list <- list("lmm1" = lmm1, "lmm2" = lmm2, "lmm3" = lmm3, "lmm4" = lmm4, "lmm5" = lmm5)
do.call(anova, c(models_list[[1]], models_list[-1]))
Warning in anova.merMod(new("lmerMod", resp = new("lmerResp", .xData = <environment>), :
failed to find model names, assigning generic names
Ich erhalte das Ergebnis, aber mit den durch die Warnung vermerkten generischen Namen, also das gleiche Ergebnis, als ob models_list
es nicht benannt worden wäre. Ich fragte auch auf Github (https://github.com/lme4/lme4/issues/612), aber mit do.call
scheint, dass ich dieses Problem nicht lösen kann. Gibt es einen anderen Weg?
Reproduzierbares Beispiel
library(lme4)
fm1 <- lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
fm2 <- lmer(Reaction ~ Days + (Days || Subject), sleepstudy)
anova(fm1,fm2)
refitting model(s) with ML (instead of REML)
Data: sleepstudy
Models:
fm2: Reaction ~ Days + ((1 | Subject) + (0 + Days | Subject))
fm1: Reaction ~ Days + (Days | Subject)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
fm2 5 1762.0 1778.0 -876.00 1752.0
fm1 6 1763.9 1783.1 -875.97 1751.9 0.0639 1 0.8004
# so I can see fm2 and fm2, to which model corresponds each line, but
models_list <- list("fm1" = fm1, "fm2" = fm2)
do.call(anova, c(lmaux[[1]], lmaux[-1]))
Warning in anova.merMod(new("lmerMod", resp = new("lmerResp", .xData = <environment>), :
failed to find model names, assigning generic names
refitting model(s) with ML (instead of REML)
Data: sleepstudy
Models:
MODEL2: Reaction ~ Days + ((1 | Subject) + (0 + Days | Subject))
MODEL1: Reaction ~ Days + (Days | Subject)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
MODEL2 5 1762.0 1778.0 -876.00 1752.0
MODEL1 6 1763.9 1783.1 -875.97 1751.9 0.0639 1 0.8004
so die Modellnamen fm1
, fm2
wurden ersetzt durch MODEL2
, MODEL1
; Dies ist ein Problem, wenn die Modellnamen durch Ändern (möglicherweise nicht aufeinanderfolgender) Nummern angegeben werden.
Ich habe mögliche Fragen geprüft, bei denen es sich um eine Art Duplikat handeln würde
- Wie übergebe ich eine Liste an eine Funktion in R?
- Übergeben Sie eine unvollständige Liste von Argumenten an do.call ()
- So übergeben Sie ein zusätzliches Argument an das Funktionsargument von do.call in R.
habe aber keine zufriedenstellende Antwort gefunden.
Vielen Dank!
Antworten
anova.merMod
Verwendet eine nicht standardmäßige Bewertung (NSE), um die Modellnamen abzurufen. Wie so oft ist NSE mehr Ärger als es wert ist. Hier ist eine Lösung:
eval(
do.call(
call,
c(list("anova"),
lapply(names(models_list), as.symbol)),
quote = TRUE),
models_list)
#refitting model(s) with ML (instead of REML)
#Data: sleepstudy
#Models:
#fm2: Reaction ~ Days + ((1 | Subject) + (0 + Days | Subject))
#fm1: Reaction ~ Days + (Days | Subject)
# npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
#fm2 5 1762.0 1778.0 -876.00 1752.0
#fm1 6 1763.9 1783.1 -875.97 1751.9 0.0639 1 0.8004
Die Lösung erstellt einen Anruf. Dies geschieht call
wie gewohnt mit der Funktion. Hier müssen wir jedoch die (zitierten) Argumente als Liste mit übergeben do.call
. Wir bewerten diesen Aufruf dann in der Liste der Modelle.
Ich würde versuchen, dies im Produktionscode zu vermeiden, da es ziemlich komplex und daher schwierig zu warten ist.