如何向自定义函数传递任意估计调用并动态添加data参数?
解决R中自定义函数传递估计调用时的提前求值问题
问题核心
直接传递lm(mpg ~ cyl)这类已求值的调用会触发R的提前求值机制——R会先在全局环境执行lm(mpg ~ cyl),而非等到自定义函数内部指定数据子集后再运行,因此出现object 'mpg' not found的错误。
解决方案
方法1:传递未求值的调用表达式,动态修改data参数
通过substitute捕获传入的调用表达式,为其添加指定的data参数后再执行:
data("mtcars") foo = function(my_call, data) { # 为调用表达式添加/替换data参数 my_call$data = substitute(data) # 在父环境中执行修改后的调用 eval(my_call, parent.frame()) } # 调用时直接传入模型调用表达式(不要提前求值) foo(lm(mpg ~ cyl), data = mtcars[1:20, ])
方法2:使用闭包(函数工厂)包装模型逻辑
先将模型函数和公式封装成一个仅接收data参数的闭包,再传递给自定义函数:
data("mtcars") # 函数工厂:生成接收data参数的模型函数 make_model_fun = function(model_fun, formula) { function(data) { model_fun(formula, data = data) } } foo = function(myfun, data) { myfun(data = data) } # 生成包装好的lm函数 lm_fun = make_model_fun(lm, mpg ~ cyl) # 传入自定义函数运行 foo(lm_fun, data = mtcars[1:20, ])
通用性验证(以fixest::feols为例)
两种方法都支持其他估计函数,比如fixest::feols:
library(fixest) # 方法1示例 foo(feols(mpg ~ cyl | vs), data = mtcars[1:20, ]) # 方法2示例 feols_fun = make_model_fun(feols, mpg ~ cyl | vs) foo(feols_fun, data = mtcars[1:20, ])
内容的提问来源于stack exchange,提问作者pbaylis
相关产品推荐
相关产品推荐

