Как передать именованный список аргументу точек (`...`) функции (в частности, `anova`) в R? (альтернативы do.call)

У меня есть список выходных смешанных моделей 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; это проблема, если названия моделей даются путем изменения (возможно, непоследовательных) номеров.

Я проверил возможные вопросы, из которых эти были бы своего рода дубликатами, поскольку

но не нашел удовлетворительного ответа.

Спасибо!

Можете ли вы предоставить минимальный воспроизводимый пример? do.call определенно передает имена параметров.

Roland 15.12.2020 11:30

@Roland Я добавил теперь MRE

iago 15.12.2020 11:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
111
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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. Затем мы оцениваем этот вызов в списке моделей.

Я бы постарался избежать этого в производственном коде, потому что он довольно сложный и, следовательно, его трудно поддерживать.

Спасибо! Замечательно! Я хотел бы спросить вас о нескольких вещах. С одной стороны, было бы здорово, если бы вы немного объяснили свой ответ, а с другой стороны, причину вашего комментария в конце

iago 15.12.2020 13:29

Смотрите правки. Вы можете посмотреть построенный вызов, удалив eval.

Roland 15.12.2020 13:40

Другие вопросы по теме

Похожие вопросы