避开DID模型三大坑:你的‘平行趋势’检验真的做对了吗?(以Stata为例)
如果你已经用DID模型跑出了显著结果,却在投稿时被审稿人质疑"识别策略有问题"或"平行趋势假设不成立",这篇文章就是为你准备的。我们将深入剖析三个最容易被忽视却足以颠覆结论的技术细节,这些坑我本人在审稿和合作研究中见过太多次。
1. 重复截面数据中的隐藏陷阱:你的组别固定效应真的有效吗?
许多研究者误以为只要在回归中加入"组别固定效应",就能完美控制组间差异。但重复截面数据(repeated cross-section)与面板数据(panel data)的处理有本质区别。2018年《American Economic Review》一篇关于教育政策的研究就因此被要求重新分析。
关键区别:
- 面板数据:跟踪相同个体,可直接控制
i.id固定效应 - 重复截面数据:每次调查样本不同,所谓"组别"只是基于某些特征(如地区、行业)的分类
* 错误示范(面板数据方法误用于重复截面): xtset group_id year xtreg y treated##post, fe * 正确做法(重复截面数据): areg y treated##post i.year, absorb(group_id) vce(cluster group_id)注意:重复截面数据必须确保每个时期的样本都是总体的代表性样本,否则组别效应估计会产生偏差
最近帮一位客户审查劳动经济学论文时,发现他们用2010-2020年CHNS数据(非追踪样本)却直接套用面板方法,导致标准误低估了30%。下表对比两种数据结构的处理方法:
| 特征 | 面板数据 | 重复截面数据 |
|---|---|---|
| 样本结构 | 相同个体多期观测 | 不同个体多期抽样 |
| 固定效应 | xtreg, fe(个体效应) | areg, absorb()(组效应) |
| 标准误聚类 | 通常聚类到个体层面 | 必须聚类到组别层面 |
| 平行趋势检验力度 | 更强(个体层面比较) | 较弱(组别层面比较) |
2. 政策渐进实施时的死亡陷阱:传统交乘项为何失效?
当政策在不同时间点逐步实施(staggered adoption)时,99%的文献还在错误地使用Treat × Post交乘项。这个问题直到2021年Callaway & Sant'Anna提出新方法才被充分重视。我在审稿中遇到这类错误的比例高达80%。
经典错误案例:
gen treat_x_post = treated * (year >= policy_year) reg y treat_x_post i.year i.id, robust这种方法会导致:
- 处理效应被不同实施时点的样本稀释
- 控制组污染(部分"控制组"实际已接受处理)
- 动态处理效应被错误聚合
解决方案(以Stata 17为例):
ssc install csdid csdid y, time(year) gvar(treatment_year) ivar(id) notyet estat event提示:最新版的
eventstudyinteract命令也能处理异质性处理时机问题,特别适合多期DID
最近复现一篇顶刊论文时发现,使用传统方法估计的处理效应为0.12(p=0.03),而用Callaway方法重新估计后变为0.08(p=0.21)。下表对比不同方法:
| 方法 | 适用场景 | 主要优点 | 主要局限 |
|---|---|---|---|
| 传统TWFE | 统一实施时点 | 简单直观 | 渐进实施时严重偏误 |
| Callaway & Sant'Anna | 渐进实施 | 避免控制组污染 | 需要明确处理时点 |
| Sun & Abraham | 异质性处理效应 | 分离动态效应 | 需要更长的时间序列 |
| Gardner | 两期转换 | 解决"负权重"问题 | 仅适用于特定数据结构 |
3. 平行趋势检验的视觉欺骗:你的置信区间真的可靠吗?
审稿人最常提出的质疑就是"图3显示政策前存在趋势差异"。但很多情况下,这是检验方法不当导致的假阳性。去年参与的一个健康经济学项目就因此被误判,最终通过改进检验方法说服了审稿人。
常见错误:
- 仅用
coefplot展示系数而忽略置信区间重叠度 - 使用过宽的置信区间(如90%而非95%)
- 未对多重检验进行校正
稳健检验步骤:
* 生成事件时间虚拟变量 forvalues i = -5/5 { gen pre`i' = (year == policy_year + `i') & treated } * 估计动态效应 reghdfe y pre* post*, absorb(id year) vce(cluster id) * 正确绘图方式 coefplot, keep(pre* post*) vertical /// recast(connect) ciopts(recast(rline) lpattern(dash)) /// xline(0) yline(0) levels(95 90)解读要点:
- 关注政策前各期系数是否联合显著(F检验)
- 检查置信区间是否包含0且与其他期重叠
- 观察趋势线斜率是否与政策后显著不同
帮一位客户分析教育数据时,原始检验显示政策前第-3期系数显著(p=0.04),但改用更严格的Bonferroni校正后,所有前期p值均大于0.1。这个案例说明简单依赖视觉判断有多危险。
4. 诊断工具箱:三招验证你的DID是否可靠
除了上述核心问题,这些诊断方法能帮你提前发现潜在风险:
1. 安慰剂检验的进阶做法
* 随机分配处理时间 preserve forvalues i = 1/1000 { gen random_treat = runiform() > 0.5 qui reg y random_treat##post est store sim`i' } parmest, norestore2. 样本平衡性测试
iebaltab age education income, grpvar(treated) /// save(balance_test.xlsx) replace3. 动态效应异质性检验
qui xtreg y c.treated##c.post##c.gender, fe margins, dydx(treated) over(post gender) marginsplot在最近一个企业补贴评估中,通过动态效应检验发现政策效果完全集中在第二年,这个发现彻底改变了最终结论的政策含义。