You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中lapply实现GLM自助抽样遇作用域问题:w未被识别原因

关于R中lapply+GLM自助抽样时公式定义位置导致权重无法识别的问题

问题重现

在R 4.3.0中用lapply做GLM的自助抽样时,遇到一个特殊问题:当把GLM的公式ff定义在匿名函数外部时,代码会报object 'w' not found的错误,但把公式放在函数内部就能正常运行。

可正常运行的代码(公式在函数内)

library(dplyr)
data_adult <- read.csv("https://raw.githubusercontent.com/guru99-edu/R-Programming/master/adult.csv")
data_adult$Y <- (data_adult$hours.per.week > 40)

iest_boot <- lapply(1:10, function(bb){
  ff <- as.formula('Y ~ gender')
  w <- rexp(nrow(data_adult), 1)
  glmout <- glm(ff, 'quasibinomial', data_adult, w)
  return(coef(glmout))
})

报错的代码(公式在函数外)

ff <- as.formula('Y ~ gender')
iest_boot <- lapply(1:10, function(bb){
  w <- rexp(nrow(data_adult), 1)
  glmout <- glm(ff, 'quasibinomial', data_adult, w)
  return(coef(glmout))
})
# 报错信息:Error in eval(extras, data, env) : object 'w' not found

问题原因

核心在于公式对象的环境绑定规则:

  • 当你在全局环境定义ff时,这个公式对象的默认绑定环境是全局环境(.GlobalEnv)。
  • glm在处理weights参数时,如果传入的是变量名(比如这里的w),它会优先在公式绑定的环境中查找这个变量,而不是当前函数的局部环境。
  • 你的w是定义在lapply匿名函数内部的局部变量,全局环境中不存在这个对象,因此会触发找不到的错误。

而把ff放在匿名函数内部时,公式的绑定环境就是这个函数的执行环境,里面正好有定义好的w,所以能正常查找。

至于全局的data_adult能被识别,是因为R的作用域规则是从当前环境向上回溯查找,glm在处理数据参数时,会从匿名函数环境往上找到全局环境,自然能拿到这个数据集。

解决办法

有两种简单的解决方式:

  • 保持公式在函数内部定义(就是你已经验证过的正常写法)。
  • 如果一定要把公式放在外部,有两种子方案:
    • 显式传入权重向量(写法更清晰直观):
      ff <- as.formula('Y ~ gender')
      iest_boot <- lapply(1:10, function(bb){
        w <- rexp(nrow(data_adult), 1)
        glmout <- glm(ff, 'quasibinomial', data_adult, weights = w)
        return(coef(glmout))
      })
      
    • 修改公式的绑定环境为当前函数环境:
      ff <- as.formula('Y ~ gender')
      iest_boot <- lapply(1:10, function(bb){
        environment(ff) <- environment() # 将公式环境切换到当前函数的局部环境
        w <- rexp(nrow(data_adult), 1)
        glmout <- glm(ff, 'quasibinomial', data_adult, w)
        return(coef(glmout))
      })
      

内容的提问来源于stack exchange,提问作者The_Anomaly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:50:04