函数内生成的multinom对象调用summary报错:object 'form' not found
自定义函数中multinom对象调用summary()报错的原因解析
问题描述
在自定义函数regression_fun中执行多项逻辑回归并返回multinom对象后,调用summary()时出现错误:
Error in stats::model.frame(formula = form, data = data_est) : object 'form' not found
但在函数外部直接创建相同的multinom对象时,summary()可正常运行;同时自定义函数regression_fun2生成glm对象并返回后,summary()能正常工作,需要明确该问题的原因。
可复现代码
rm(list=ls()) library(nnet) library(foreign) mydata <- read.dta("https://dss.princeton.edu/training/Panel101.dta") form01 <- as.formula("opinion ~ x1 + x2 + x3 + country") # 函数外执行,summary正常 regression_out <- multinom(formula = form01,data = mydata) summary(regression_out) # 自定义函数内执行,summary报错 regression_fun <- function(data_est,form){ regression <- multinom(formula = form,data = data_est) return(regression) } regs <- regression_fun(data_est=mydata,form=form01) summary(regs) # glm自定义函数,summary正常 regression_fun2 <- function(data_est,form){ regression <- glm(formula = form,data = data_est,family = binomial()) return(regression) } form02 <- as.formula("op ~ x1 + x2 + x3 + country") regs2 <- regression_fun2(data_est=mydata,form=form02) summary(regs2)
环境信息
R version 4.1.0 (2021-05-18) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 19044) Matrix products: default Random number generation: RNG: Mersenne-Twister Normal: Inversion Sample: Rounding attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] foreign_0.8-81 nnet_7.3-16
原因分析
核心问题出在nnet::multinom()和glm()对公式对象的保存机制差异:
multinom()保存模型对象时,仅记录公式的符号引用(即参数名form),而非公式的具体内容。当自定义函数执行完毕后,函数内部的局部变量form会被销毁,后续summary()调用时找不到该对象,因此报错。glm()属于基础统计包函数,会将公式的具体内容完整嵌入模型结果,即使函数执行完毕,summary()仍能获取到公式的完整信息,因此可以正常运行。
解决方法
有两种简单的修复方式:
- 转换公式为字符再转回公式:强制保存公式的具体内容,避免符号引用问题
regression_fun <- function(data_est,form){ form <- as.formula(as.character(form)) regression <- multinom(formula = form,data = data_est) return(regression) }
- 使用
force()强制求值公式:确保公式在函数内部被完整求值,而非保留符号引用
regression_fun <- function(data_est,form){ force(form) regression <- multinom(formula = form,data = data_est) return(regression) }
内容的提问来源于stack exchange,提问作者sebastiann
相关产品推荐
相关产品推荐

