从Stata/R代码实操出发:手把手教你用双重差分法(DID)评估一个‘政策’的真实效果
评估政策效果是实证研究中的常见需求,而双重差分法(DID)因其直观性和有效性成为广泛使用的工具。本文将以某城市"人才引进政策"对当地房价的影响为例,带你一步步完成从数据准备到结果解读的全流程操作。
1. 数据准备与清洗
面板数据是DID分析的基础,我们需要确保数据结构符合要求。以评估人才引进政策为例,理想的数据应包含:
- 城市层面数据:处理组(实施政策的城市)和对照组(未实施政策的城市)
- 时间维度:政策实施前后足够长的时期(通常建议前后各3-5年)
- 关键变量:
- 房价指数(结果变量)
- 政策实施时间(处理变量)
- 其他控制变量(如人口增长率、GDP增速等)
在Stata中检查数据结构:
// 查看面板数据结构 xtset city_id year xtdescribe常见问题及解决方案:
| 问题类型 | 检查方法 | 解决方案 |
|---|---|---|
| 缺失值 | misstable summarize | 删除或插补 |
| 异常值 | summarize var, detail | Winsorize处理 |
| 非平衡面板 | xtbalance, report | 平衡化处理 |
提示:平行趋势检验需要政策实施前的数据,确保收集足够长的历史数据
2. 基础DID模型实现
2.1 Stata实现
Stata的diff命令是进行DID分析的便捷工具:
// 基础DID模型 diff housing_price, t(treated) p(post) cov(pop_growth gdp_growth) kernel id(city_id) bs reps(100)关键参数解释:
treated:是否处理组的虚拟变量post:政策实施后的虚拟变量cov():加入的控制变量kernel:使用核匹配提高估计效率bs reps(100):进行100次bootstrap抽样
2.2 R语言实现
R中的fixest包提供了高效的DID估计:
library(fixest) did_model <- feols(housing_price ~ treated:post + pop_growth + gdp_growth | city_id + year, data = policy_data, vcov = "twoway") summary(did_model)模型输出解读要点:
treated:post的系数即政策效应- 关注标准误的计算方法(聚类稳健标准误)
- 检查控制变量的显著性
3. 平行趋势检验
平行趋势假设是DID有效性的核心前提,常用事件研究法验证:
// 生成相对时间变量 gen time_to_treat = year - policy_year replace time_to_treat = -5 if time_to_treat < -5 // 截断早期年份 // 事件研究回归 reghdfe housing_price ib(-1).time_to_treat#i.treated pop_growth gdp_growth, /// absorb(city_id year) vce(cluster city_id)结果解读要点:
- 政策实施前的系数应统计不显著
- 政策实施后的效应应随时间变化
- 绘制系数图直观展示趋势
注意:若平行趋势不成立,考虑使用合成控制法等其他方法
4. 稳健性检验与结果报告
完整的DID分析需要多种稳健性检验:
安慰剂检验:
- 虚构处理时间
- 随机分配处理组
控制变量敏感性:
- 不同控制变量组合
- 加入城市特定趋势
样本调整:
- 排除特殊城市
- 不同时间窗口
Stata实现安慰剂检验示例:
// 随机分配处理组 set seed 1234 gen placebo_treated = runiform() > 0.5 if treated == 1 diff housing_price, t(placebo_treated) p(post) cov(pop_growth gdp_growth)结果报告应包括:
- 基础DID估计结果
- 平行趋势检验证据
- 稳健性检验结果
- 经济意义解释(如政策使房价上涨X%)
5. 高级话题与常见陷阱
5.1 多期DID处理
当政策实施时间不同时,需要使用多期DID方法:
// 多期DID gen first_treat = policy_year // 各城市首次实施政策的年份 ivreghdfe housing_price (D = i.first_treat), absorb(city_id year) cluster(city_id)5.2 常见问题排查
- 负权重问题:检查
twowayfeweights包 - 动态效应:使用
eventstudyinteract命令 - 溢出效应:考虑空间计量方法
实际操作中遇到的典型错误:
- 忽略面板数据的双重固定效应
- 错误理解交互项系数
- 忽视标准误的聚类调整
- 对平行趋势检验的误解
# R中检查负权重 library(did) att_gt(yname = "housing_price", tname = "year", idname = "city_id", gname = "first_treat", data = policy_data)