使用feols函数拼接公式出现多余c字符的问题求解
解决R函数中拼接fixest公式时多余"c"字符的问题
问题根源
你遇到的问题是因为enexpr(arg)获取到的是完整的c(x1,x2)调用表达式,直接对这个表达式执行paste操作会把c也当作字符串的一部分保留下来,最终拼接出错误的公式D ~ c + x1 + x2 | id + period。
解决方案
下面提供几种可行的修复方式,从简单修改到更规范的公式构建方式:
方法1:提取c()调用中的参数
既然enexpr(arg)返回的是一个调用对象,我们可以通过as.list()将其拆分为列表,然后去掉第一个元素(即c本身),只保留里面的变量名:
library(dplyr) library(fixest) data(base_did) base_did = base_did %>% mutate(D = 5*rnorm(1080), x2 = 10*rnorm(1080), rand_wei = abs(rnorm(1080))) f <- function(data, arg=NULL){ arg = enexpr(arg) if (length(arg) == 0) { formula = "D ~ 1" } else { # 提取c()中的变量参数,移除第一个元素"c" arg_vars <- as.list(arg)[-1] formula = paste("D ~ ", paste(arg_vars, collapse = " + "), sep = "") } formula = paste(formula, " | id + period", sep = "") denom.lm <- feols(as.formula(formula), data = data, weights = abs(data$rand_wei)) return(denom.lm) } # 测试调用 f(base_did, arg = c(x1,x2))
方法2:改用ensyms()解析变量
ensyms()可以直接将传入的c(x1,x2)解析为符号列表,自动忽略c,无需额外处理:
f <- function(data, arg=NULL){ arg_syms <- ensyms(arg) if (length(arg_syms) == 0) { formula = "D ~ 1" } else { formula = paste("D ~ ", paste(arg_syms, collapse = " + "), sep = "") } formula = paste(formula, " | id + period", sep = "") denom.lm <- feols(as.formula(formula), data = data, weights = abs(data$rand_wei)) return(denom.lm) }
方法3:用reformulate()构建公式(推荐)
避免字符串拼接,直接操作公式对象是更安全的方式,reformulate()可以帮你快速构建公式,再用update()添加固定效应部分:
f <- function(data, arg=NULL){ arg_syms <- ensyms(arg) # 构建核心回归公式 core_formula <- if (length(arg_syms) == 0) { reformulate("1", response = "D") } else { reformulate(as.character(arg_syms), response = "D") } # 添加固定效应项 full_formula <- update(core_formula, . ~ . | id + period) denom.lm <- feols(full_formula, data = data, weights = abs(data$rand_wei)) return(denom.lm) }
这种方式完全避免了手动拼接字符串可能带来的错误,代码可读性和健壮性更强。
内容的提问来源于stack exchange,提问作者user20168262
相关产品推荐
相关产品推荐

