R에서 함수 (특히`anova`)의 점 (`…`) 인수에 명명 된 목록을 전달하는 방법은 무엇입니까? (`do.call`의 대안)

Dec 15 2020

lme4::lmer전달하려는 혼합 모델 출력 목록 anova이 있고 형식 anova(object, ...)이 있으므로

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

나는 결과를 얻었지만 경고로 표시된 일반 이름으로 인해 이름 models_list이 지정되지 않은 것과 동일한 결과가 나타납니다 . 나는 또한 github (https://github.com/lme4/lme4/issues/612)을 사용했지만 do.call이 문제를 해결할 수없는 것 같습니다. 다른 방법이 있습니까?

재현 가능한 예

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

모델 이름 때문에 fm1, fm2교환되었다 MODEL2, MODEL1; 모델 이름이 (연속적이지 않은) 번호를 변경하여 제공되는 경우 문제가됩니다.

나는 이것들이 일종의 중복 일 가능성이있는 질문을 확인했습니다.

  • R의 함수에 목록을 전달하는 방법은 무엇입니까?
  • do.call ()에 인수의 일부 목록을 전달합니다.
  • R에서 do.call의 함수 인수에 추가 인수를 전달하는 방법

그러나 만족스러운 답을 찾지 못했습니다.

감사합니다!

답변

2 Roland Dec 15 2020 at 18:50

anova.merMod비표준 평가 (NSE)를 사용하여 모델 이름을 가져옵니다. 종종 그렇듯이 NSE는 가치보다 문제가 더 많습니다. 해결책은 다음과 같습니다.

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

솔루션이 호출을 생성합니다. 그것은 call평소 와 같이 기능으로 수행됩니다 . 그러나 여기서 우리는를 사용하여 (인용 된) 인수를 목록으로 전달해야합니다 do.call. 그런 다음 모델 목록에서이 호출을 평가합니다.

꽤 복잡하고 유지 관리가 어렵 기 때문에 프로덕션 코드에서 이것을 피하려고합니다.