【问题标题】:Non-standard evaluation with mgcv::gam使用 mgcv::gam 进行非标准评估
【发布时间】:2018-12-12 10:03:17
【问题描述】:

我正在制作一个函数,它将对回归函数的未评估调用作为输入,创建一些数据,然后评估调用。这是一个例子:

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) 应该在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

【问题讨论】:

    标签: r gam mgcv


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 2016-09-18
      相关资源
      最近更新 更多