lapply, glm и speedglm внутри функции: аргумент «data» отсутствует, по умолчанию нет - PullRequest
2 голосов
/ 03 ноября 2019

Я использую данные mtcars, чтобы показать мою проблему. Следующий код отлично работает с glm. Он генерирует новые модели, добавляя каждую переменную в vlist к модели glm(vs ~ mpg, family = binomial(), data = mtcars.

check_glm <- function(crude, vlist, data, ...){
  a <- glm(crude, data = data, family = binomial())
  lapply(vlist, function(x) update(a, as.formula(paste0(". ~ . +", x))))
}
check_glm(crude = "vs ~ mpg", vlist = c("am", "hp"), data = mtcars)

Однако, когда я заменил glm на speedglm,

library(speedglm)
check_speedglm <- function(crude, vlist, data, ...){
  a <- speedglm(crude, data = data, family = binomial())
  lapply(vlist, function(x) update(a, as.formula(paste0(". ~ . +", x))))
}
check_speedglm(crude = "vs ~ mpg", vlist = c("am", "hp"), data = mtcars)

, я получил:

Ошибка в model.frame.default(формула = vs ~ mpg + am, data = data, drop.unused.levels = TRUE): аргумент "data" отсутствует, по умолчанию нет.

Я думаю, что проблема в lapply, но я не смог найти решение. Любые предложения, чтобы исправить это будет оценено.

1 Ответ

3 голосов
/ 03 ноября 2019

По сути, вы путаете методы пакета, которые могут быть несовместимы друг с другом. Хотя они имеют одно и то же имя, оба эти метода относятся к разным пакетам, поэтому разные авторы для разных целей и выводят разные объекты (класс glm против класса speedglm, который может быть объектами S3 и S4).

В частности, метод glm является частью стандартной библиотеки R в пакете stats, которая работает со связанным с ним методом stats, update.

За update документы,

update обновит и (по умолчанию) обновит модель. Это делается путем извлечения вызова, хранящегося в объекте, обновления вызова и (по умолчанию) оценки этого вызова.

Основной аргумент:

объект, x : существующее соответствие из функции модели, такой как lm, glm и многие другие

Следовательно, если speedglm сохраняет вызов для захвата формулы, данных и других аргументов и напоминает структуру возвращаемого объекта как glm (которая наследуется от lm класса), то update будет работать.


Чтобы разрешить проблему, подумайте о том, чтобы делать то, что делает * 1038, путем динамического построения formula с итерационными вызовами модели с использованием lapply. Это будет работать в обоих методах, так как каждый использует объект formula.

library(speedglm) 

check_speedglm <- function(crude, vlist, data, ...){ 
   lapply(seq_along(vlist), function(i)
       speedglm(as.formula(paste(crude, "+", paste(vlist[1:i], collapse=" + "))), 
                data = data, family = binomial()) 
   )
} 

check_speedglm(crude = "vs ~ mpg", vlist = c("am", "hp"), data = mtcars)
...