如何在fixest::feols()中无需字符串转公式引用外部变量构建subset
问题:fixest::feols()自定义函数中程序化构建subset公式的最优方法
在使用fixest::feols()函数时,尝试通过自定义函数传递参数,利用subset =参数实现数据子集筛选,却持续收到报错:
‘参数'subset'是一个公式,其变量必须位于参数'data'指定的数据集中。’
尝试的代码如下:
library(fixest) cars <- mtcars my_fun <- function(data, hp.c.off) { feols(mpg ~ disp + drat, data = data, subset = ~ hp > substitute(hp.c.off)) } my_fun(data = cars, 150)
预期执行效果等同于直接运行:
feols(mpg ~ disp + drat, data = cars, subset = ~ hp > 150)
已知可以通过构建字符串表达式再用as.formula()转换实现,但希望找到无需字符串转公式的更优方法来程序化构建该表达式。
解决方案
方案1:使用bquote()结合eval()
bquote()可以保留表达式结构,同时替换指定变量,再通过eval()执行替换后的公式:
library(fixest) cars <- mtcars my_fun <- function(data, hp.c.off) { feols(mpg ~ disp + drat, data = data, subset = eval(bquote(~ hp > .(hp.c.off)))) } my_fun(data = cars, 150)
这里.(hp.c.off)会将函数参数的实际值直接注入公式,生成~ hp > 150的正确表达式,完全不需要字符串转换。
方案2:使用rlang的表达式注入
如果熟悉tidyverse生态,可借助rlang包的expr()和!!操作符实现参数注入:
library(fixest) library(rlang) cars <- mtcars my_fun <- function(data, hp.c.off) { sub_formula <- expr(~ hp > !!hp.c.off) feols(mpg ~ disp + drat, data = data, subset = sub_formula) } my_fun(data = cars, 150)
!!(bang-bang)操作符会强制将hp.c.off的实际值注入表达式,生成目标公式,同样无需字符串转换步骤。
方案3:直接用fixest的fsubset处理数据
fixest内置的fsubset()函数可直接对数据集进行筛选,绕开构建subset公式的步骤,代码更直观:
library(fixest) cars <- mtcars my_fun <- function(data, hp.c.off) { feols(mpg ~ disp + drat, data = fsubset(data, hp > hp.c.off)) } my_fun(data = cars, 150)
这种方式直接在数据层面完成筛选,可读性和维护性都更强。
内容的提问来源于stack exchange,提问作者cach1
相关产品推荐
相关产品推荐

