MatchIt::matchit()不支持公式变量排除?原因及解决方法
关于MatchIt中公式排除变量的问题及解决办法
问题背景
希望在matchit()的公式中排除net_tfa变量,但后续仍需保留并使用该变量。对比lm()支持~ . -变量的排除方式,matchit()无法识别这种语法,导致net_tfa仍被当作协变量纳入匹配过程,示例代码如下:
# toy data # install.packages("hdm") library(hdm); data("pension") # allowing convergence pension <- pension[, c("p401", "net_tfa", "age", "db", "educ","fsize", "hown", "inc", "male", "marr","pira", "twoearn")] lm(p401 ~ . -net_tfa, data = pension) #> #> Call: #> lm(formula = p401 ~ . - net_tfa, data = pension) #> #> Coefficients: #> (Intercept) age db educ fsize hown #> 9.865e-02 -1.718e-03 1.174e-01 3.975e-04 -3.112e-03 6.556e-02 #> inc male marr pira twoearn #> 3.967e-06 -1.347e-02 -1.027e-02 6.407e-02 2.519e-02 # install.packages("MatchIt") library(MatchIt) matchit(formula = p401 ~ . -net_tfa, data = pension, method = "nearest", link = "probit", estimand = "ATT", replace = TRUE) #> A matchit object #> - method: 1:1 nearest neighbor matching with replacement #> - distance: Propensity score #> - estimated with probit regression #> - number of obs.: 9915 (original), 4435 (matched) #> - target estimand: ATT #> - covariates: net_tfa, age, db, educ, fsize, hown, inc, male, marr, pira, twoearn
原因解析
matchit()的公式解析逻辑和lm()存在差异:
lm()等线性模型函数的公式语法中,~ . -变量是标准的“包含所有变量除指定变量”的写法;- 但
MatchIt包的matchit()函数在解析公式时,不会处理公式中的减号操作。它会直接将~ .理解为包含处理变量(此处为p401)之外的所有变量,完全忽略后面的-net_tfa部分,这是函数设计时的语法规则限制。
解决办法
以下几种方式可以实现排除指定变量,同时保留该变量在数据中供后续使用:
方法1:手动列出协变量
直接在公式中写出所有需要用于匹配的协变量,不包含net_tfa:
matchit(formula = p401 ~ age + db + educ + fsize + hown + inc + male + marr + pira + twoearn, data = pension, method = "nearest", link = "probit", estimand = "ATT", replace = TRUE)
这种方式直观易懂,适合协变量数量较少的场景。
方法2:动态生成公式
如果协变量数量较多,可先构造排除net_tfa后的变量名向量,再用reformulate()生成公式:
# 获取除处理变量p401和要排除的net_tfa之外的所有变量名 covars <- setdiff(names(pension), c("p401", "net_tfa")) # 生成匹配公式并运行matchit matchit(formula = reformulate(covars, response = "p401"), data = pension, method = "nearest", link = "probit", estimand = "ATT", replace = TRUE)
这种方式灵活性高,后续调整排除变量时只需修改setdiff()中的向量即可。
方法3:用update()预处理公式
先定义全变量公式,再用update()移除指定变量,避免matchit()直接解析带减号的原公式:
# 定义包含所有变量的初始公式 full_formula <- p401 ~ . # 移除net_tfa变量 match_formula <- update(full_formula, ~ . - net_tfa) # 运行匹配 matchit(formula = match_formula, data = pension, method = "nearest", link = "probit", estimand = "ATT", replace = TRUE)
内容的提问来源于stack exchange,提问作者user14692575
相关产品推荐
相关产品推荐

