避开DID分析的大坑:你的‘平行趋势’检验真的做对了吗?(附Stata事件研究法代码)
在应用双重差分法(DID)进行政策评估时,"平行趋势"检验往往是决定研究可信度的关键环节。然而,许多研究者在实际操作中容易陷入几个典型误区:要么仅凭简单的均值趋势图就草率下结论,要么在事件研究法的代码实现上存在技术漏洞。本文将深入剖析这些常见问题,并提供一套可直接用于学术论文的Stata实操方案。
1. 为什么均值趋势图不足以验证平行趋势?
许多论文中常见的做法是绘制处理组和对照组在政策实施前后的均值变化趋势图,然后通过肉眼观察两组在政策前的趋势是否"平行"。这种方法存在三个根本缺陷:
- 缺乏统计显著性判断:视觉上的"平行"可能掩盖实际存在的统计差异
- 忽略时间维度异质性:整体趋势可能掩盖特定时段的偏离
- 无法量化政策动态效应:难以捕捉政策效果的时变特征
提示:审稿人越来越关注平行趋势检验的严谨性,简单的趋势图往往难以通过严格的同行评议。
更科学的做法是采用事件研究法(Event Study),它能够:
- 量化每个时期处理效应的统计显著性
- 识别政策效果的动态变化模式
- 提供更直观的系数可视化呈现
2. 事件研究法的Stata实现详解
2.1 关键变量构建逻辑
正确的变量构造是事件研究法的核心。以下代码展示了如何生成政策前后各期的交互项:
// 计算距离政策实施的相对年份 gen period = year - policy_year // 生成政策前虚拟变量 forvalues i = 3(-1)1{ gen pre_`i' = (period == -`i' & treated == 1) } // 生成政策当期虚拟变量 gen current = (period == 0 & treated == 1) // 生成政策后虚拟变量 forvalues j = 1(1)3{ gen time_`j' = (period == `j' & treated == 1) } // 避免多重共线性(以pre_1为基准期) drop pre_1这段代码的关键点在于:
period变量将绝对时间转换为相对政策时点的位置- 前导项(
pre_*)和滞后项(time_*)的期数应根据实际数据特点调整 - 必须drop一个基准期以避免完全共线性
2.2 模型设定与估计
推荐使用面板固定效应模型进行估计:
xtreg outcome_var i.year pre_* current time_*, fe vce(cluster id) est sto event_study模型设定注意事项:
- 必须加入年份固定效应(
i.year)控制共同时间冲击 - 使用聚类标准误(
vce(cluster id))处理序列相关问题 - 存储估计结果(
est sto)为后续可视化做准备
3. 专业级系数图的制作与解读
3.1 使用coefplot命令可视化
coefplot命令可以生成出版级的系数图:
coefplot event_study, /// keep(pre_* current time_*) /// vertical /// recast(connect) /// yline(0) xline(4, lp(dash)) /// ciopts(lpattern(dash) recast(rcap)) /// msymbol(circle_hollow) /// scheme(s1mono) /// title("事件研究法结果") /// ytitle("处理效应") /// xtitle("相对政策时点")参数说明:
vertical:将系数垂直排列yline(0):在y=0处画参考线xline(4):在政策时点处画虚线ciopts:设置置信区间样式
3.2 结果解读要点
一张合格的事件研究图应该显示:
- 政策前的系数在0附近波动且不显著(置信区间包含0)
- 政策后的系数呈现预期方向的变化
- 没有明显的预趋势(pre-trend)问题
常见错误解读:
- 将政策前不显著的系数误认为"平行趋势成立"
- 忽略置信区间的宽度变化
- 对政策后效应的持续性判断失误
4. 高级稳健性检验技巧
4.1 动态效应检验
通过扩展事件研究法的期数,检验政策效果的动态模式:
// 扩展至政策前后各5期 forvalues i = 5(-1)1{ gen pre_`i' = (period == -`i' & treated == 1) } forvalues j = 1(1)5{ gen time_`j' = (period == `j' & treated == 1) } drop pre_1 xtreg outcome_var i.year pre_* current time_*, fe vce(cluster id)4.2 安慰剂检验
通过虚构政策时点进行反事实检验:
// 随机生成虚构政策年份 gen placebo_year = floor(1990 + runiform()*(2000-1990)) gen placebo_period = year - placebo_year // 构建虚构交互项 forvalues i = 3(-1)1{ gen placebo_pre_`i' = (placebo_period == -`i' & treated == 1) } gen placebo_current = (placebo_period == 0 & treated == 1) forvalues j = 1(1)3{ gen placebo_time_`j' = (placebo_period == `j' & treated == 1) } drop placebo_pre_1 // 估计安慰剂模型 xtreg outcome_var i.year placebo_pre_* placebo_current placebo_time_*, fe vce(cluster id)预期结果:虚构政策时点的处理效应应该不显著,否则可能暗示模型设定存在问题。
4.3 异质性分析
检验处理效应在不同子样本中的差异:
// 按企业规模分组检验 xtreg outcome_var i.year pre_* current time_* if size==1, fe vce(cluster id) est sto small xtreg outcome_var i.year pre_* current time_* if size==0, fe vce(cluster id) est sto large coefplot small large, /// keep(pre_* current time_*) /// bycoefs /// vertical /// yline(0) /// scheme(s1mono)这种分析可以揭示政策效果的异质性,增强研究的深度。