Нестандартная оценка с mgcv::gam

Я делаю функцию, которая принимает в качестве входных данных неоцененные вызовы функций регрессии, создает некоторые данные, а затем оценивает вызов. Вот пример:

library(lme4)
compute_fit <- function(m){
  # Generate some data
  df <- data.frame(x = rnorm(100), y = rnorm(100) + x, ID = sample(4, 100, replace = TRUE))
  # Evaluate the call
  eval(m, envir = df)
}

# Create a list of models
models <- list(
  lm = call("lm", quote(list(formula = y ~ x))),
  glm = call("glm", quote(list(formula = y ~ x))),
  lmer = call("lmer", quote(list(formula = y ~ x + (1 | ID))))
)

# Evaluate the call (this works fine)
model_fits <- lapply(models, compute_fit)

Моя причина для этого заключается в том, что я провожу симуляционное исследование, в котором я подгоняю множество разных моделей ко многим образцам Монте-Карло. Функция является частью внутреннего пакета, и я хочу предоставить список моделей, которые затем оцениваются внутри пакета.

Я хотел бы также использовать gam функция от mgcv, В документации к gam сказано следующее data аргумент, который практически эквивалентен, например, документации к lm:

Фрейм данных или список, содержащий переменную ответа модели и ковариаты, необходимые для формулы. По умолчанию переменные берутся из среды (формула): обычно это среда, из которой вызывается гам.

Поэтому я пытаюсь использовать ту же логику для вычисления gamдумая что eval(m, envir = df) в compute_fit Определенная выше функция должна оценивать формулу в среде df:

# Try with gam
library(mgcv)
gamcall = call("gam", quote(list(formula = y ~ x)))    
compute_fit(gamcall)  

Тем не менее, это не с сообщением об ошибке:

Ошибка в eval(predvars, data, env): объект 'y' не найден

Я понимаю, что эта ошибка, вероятно, связана с этим вопросом, однако мой вопрос заключается в том, может ли кто-нибудь придумать обходной путь, который позволяет мне использовать gam так же, как я использую другие функции моделирования? Насколько я понимаю, связанный вопрос не дает решения этого вопроса.

Вот полное представление:

set.seed(1)
library(lme4)
#> Loading required package: Matrix
compute_fit <- function(m){
  # Generate some data
  df <- data.frame(x = rnorm(100), ID = rep(1:50, 2))
  df$y <- df$x + rnorm(100, sd = .1)
  # Evaluate the call
  eval(m, envir = df)
}

# Create a list of models
models <- list(
  lm = call("lm", quote(list(formula = y ~ x))),
  glm = call("glm", quote(list(formula = y ~ x))),
  lmer = call("lmer", quote(list(formula = y ~ x + (1 | ID))))
)

# Evaluate the call (this works fine)
model_fits <- lapply(models, compute_fit)

# Try with gam
library(mgcv)
#> Loading required package: nlme
#> 
#> Attaching package: 'nlme'
#> The following object is masked from 'package:lme4':
#> 
#>     lmList
#> This is mgcv 1.8-26. For overview type 'help("mgcv-package")'.
gamcall = call("gam", quote(list(formula = y ~ x)))    
compute_fit(gamcall)    
#> Error in eval(predvars, data, env): object 'y' not found

1 ответ

Решение

Я бы добавил df на вызов вместо оценки в df:

compute_fit <- function(m){
  # Generate some data
  set.seed(1)
  df <- data.frame(x <- rnorm(100), y = rnorm(100) + x^3, ID = sample(4, 100, replace = TRUE))
  #add data parameter to call
  m[["data"]] <- quote(df)
  # Evaluate the call
  eval(m)
}

# Create a list of models
models <- list(
  lm = quote(lm(formula = y ~ x)),
  glm = quote(glm(formula = y ~ x)),
  lmer = quote(lmer(formula = y ~ x + (1 | ID))),
  gam = quote(gam(formula = y ~ s(x)))
)

model_fits <- lapply(models, compute_fit)
#works but lmer reports singular fit
Другие вопросы по тегам