我正在制作一个函数,该函数将对回归函数的未评估调用作为输入,创建一些数据,然后评估该调用。这是一个示例:
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的环境。
因此,我尝试使用相同的逻辑来计算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”
我意识到此错误很可能与this question有关,但是我的问题是,是否有人能想到一种解决方法,可以让我像使用其他建模函数一样使用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
答案 0 :(得分:3)
我会在通话中添加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