[英]Non-standard evaluation with 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)
我這樣做的原因是,我正在進行模擬研究,我在許多蒙特卡羅樣本上擬合了許多不同的模型。 該函數是內部包的一部分,我想提供模型列表,然后在包內進行評估。
我還想使用mgcv
的gam
函數。 在gam的文檔中,以下是關於其data
參數的說明,它實際上等同於例如lm
的文檔:
包含模型響應變量和公式所需協變量的數據框或列表。 默認情況下,變量取自環境(公式):通常是調用gam的環境。
因此,我嘗試使用相同的邏輯來計算gam
,認為上面定義的compute_fit
函數中的eval(m, envir = df)
compute_fit
eval(m, envir = df)
應該評估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
我會在調用中添加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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.