在R函数中调用glm时无法找到环境内公式的问题求助
R中glm模型update时找不到公式的问题解决
问题原因
在fun2的局部环境中创建公式fmla并拟合glm模型时,公式对象会绑定当前的函数执行环境(即fun2的局部环境)。当fun2执行完毕返回后,这个局部环境会被R的垃圾回收机制清理。后续在fun1中调用update函数时,需要重新评估模型的公式,但此时公式绑定的环境已不存在,因此触发object 'fmla' not found错误。
你尝试的environment(fmla) <- environment()无效,是因为该语句仍将公式绑定到fun2的局部环境,并未解决后续环境被回收的问题。而使用<<-赋值虽然能运行,但会将fmla写入全局环境,污染全局命名空间,多次调用会覆盖全局变量,存在潜在bug。
解决方案
方案1:在fun1中直接重新拟合模型(推荐)
放弃使用update,直接提取原模型的公式,在训练集上重新拟合,彻底规避环境依赖问题:
n <- 20 ncov <- 3 df <- as.data.frame(replicate(ncov+1, runif(n))) names(df) <- c(paste0("x", seq(ncov)), "y") fun1 <- function(mod, pTrain = 0.5){ data <- mod$data train <- sample(nrow(data), size = nrow(data)*pTrain) valid <- -train # 提取原模型公式,在训练集重新拟合 modTrain <- glm(formula = formula(mod), data = data[train,]) yhat <- predict(modTrain, newdata = data[valid,]) # 修正原代码的长度不匹配问题:仅保留验证集的真实y值 res <- data.frame(y = data$y[valid], yhat = yhat) return(res) } fun2 <- function(useCovs = c(1,0,0), data = df){ fmla <- formula(paste("y ~", paste(paste0("x", seq(useCovs))[as.logical(useCovs)], collapse = " + "))) mod <- glm(formula = fmla, data = data) res <- fun1(mod, pTrain = 0.5) score <- sqrt(mean((res$y - res$yhat)^2)) return(c(aic = AIC(mod), rmse = score)) } fun2(useCovs = c(1,0,1)) # 正常运行
方案2:绑定公式到全局环境(不推荐)
若坚持使用update,可将公式的环境设置为全局环境,确保后续调用时变量可被找到,但此方法会污染全局命名空间:
fun2 <- function(useCovs = c(1,0,0), data = df){ fmla <- formula(paste("y ~", paste(paste0("x", seq(useCovs))[as.logical(useCovs)], collapse = " + "))) environment(fmla) <- .GlobalEnv # 将公式环境绑定到全局 mod <- glm(formula = fmla, data = data) res <- fun1(mod, pTrain = 0.5) score <- sqrt(mean((res$y - res$yhat)^2)) return(c(aic = AIC(mod), rmse = score)) }
方案3:直接传递公式字符串给glm
构造公式字符串并直接传入glm,glm会自动解析为公式并绑定到数据环境,避免依赖函数局部环境:
fun2 <- function(useCovs = c(1,0,0), data = df){ fmla_str <- paste("y ~", paste(paste0("x", seq(useCovs))[as.logical(useCovs)], collapse = " + ")) mod <- glm(formula = fmla_str, data = data) res <- fun1(mod, pTrain = 0.5) score <- sqrt(mean((res$y - res$yhat)^2)) return(c(aic = AIC(mod), rmse = score)) }
内容的提问来源于stack exchange,提问作者Marc in the box
相关产品推荐
相关产品推荐

