Нестандартная оценка с 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