分享

双重差分平行趋势如何添加基期

 我是张金康呀 2022-01-11

一、写在前面

在使用双重差分因果识别时,重要的假设是处理组和对照组满足平行趋势。通常的做法是直接绘制处理组和对照组的结果变量,以观测在政策前两组样本结果变量趋势是否一致。比如,AEJ:Policy即将发表的一篇文章,研究大学选址如何影响地方创新的文章(Andrews,2022,Forthcoming)。作者绘制了处理组和对照组所在地区创新水平的变动趋势,如下图所示。可以发现,在政策前,处理组(蓝色线)与对照组(红色线)之间变动趋势完全一致。而在政策之后,处理组创新水平明显高于对照组。这张图在一定程度上可以表明满足DID的识别假设。

图片

事实上,使用原始数据(row data)的结变量绘制平行趋势一般难以满足。因此,更为常见的是使用政策虚拟变量与每一年的年份虚拟变量交互,观测政策发生前后的系数是否显著。一般认为,在政策发生前系数不显著,政策发生后系数显著,则表明满足平行趋势。那么以这种方式验证平行趋势,就会涉及到选择以哪一年为基期(参考组)。部分研究会选择政策前1期为参考,也有研究选择第1期为参考。这个具体选择需要根据研究具体内容选择。

另一个很重要的问题是,如何将基期的0值在平行趋势的图中呈现。呈现基期的0值有2个好处:

  • 第一,便于读者从图中清楚的看到作者选择的哪一期为参考;

  • 第二,一般加上基期的0值后看起来更满足平行趋势。

下图分别是添加了基期和未添加基期的两张图(两张图源于论文两个版本,数值略有差异)。虽然都比较丑,但是第二张图至少可以清楚的看到使用了哪一期作为基期。

图片
图片

二、Stata如何实现

上文的第二张图其实很好实现,更多的人可能更纠结第三张图如何将基期的0点添加上去。为了便于对下图结果复制,我借用了子尧师兄他们发表在产业经济评论文章的代码,进行演示说明。

1. 生成模拟数据

这部分完全使用子尧师兄他们发表在产业经济评论文章的代码(在此表示感谢)。最终生成的simu_data是本文演练使用的数据集。

/*-----------------------------------------------------------------
|                 DiD Method and It's Applications                |
|                          April 2021                             |
|               Huang Wei  Zhang ZiYao  Liu AnRan                 |
|                                                                 |
| Wirtten by Zhang ZiYao                                          |
| Required packages: reghdfe; coefplot                            |
-----------------------------------------------------------------*/
 
***********************
**  1.Generate Data  **
***********************
    clear all    
    set obs 200
    gen id = _n
    expand 20
    bysort id: gen time = _n  

    * 生成个体固定效应
    gen  unit_c     = runiform() if time==1
    egen unit_spec  = mean(unit_c), by(id)

    * 协变量x根据个体固定效应生成,与个体固定效应相关
    gen x = rnormal(unit_spec)


    * 定义处理组为前100人,处理期为第11期
    gen     treat = 0
    gen     indicator_c = unit_c + x
    qui sum indicator_c,d
    scalar  threshold   = r(p50)
    egen    indicator   = mean(indicator_c), by(id)
    replace treat = 1 if indicator>threshold
    gen     post  = 0
    replace post  = 1 if time>=11
    gen     D     = treat*post

    * 生产结果变量w
    gen u  = rnormal() // u不是error term,而是同时影响w和y的不可观测因素
    gen w0 = 0 + u - runiform()
    gen w1 = 1 + u - runiform()
    gen w  = (1-D)*w0 + D*w1

    * 定义潜在结果y0和y1
    gen y0 = 0 + unit_spec + 1*x + u + 0.1*time  + runiform(0,1)
    gen y1 = 1 + unit_spec + 1*x + u + 0.1*time  + runiform(0,1)

    * 生成观测样本y 
    cap drop y
    gen y = (1-D)*y0 + D*y1 

save  simu_data, replace

为了更好的理解数据生成的变量,建议大家阅读产业经济评论上的原文。数据中处理期为第11期,实验组为treat变量。

2. 生成无基期的平行趋势图

这一部分是基于子尧师兄提供代码,我进行修正后生成的无基期的平行趋势图。其代码如下:

use data\simu_data, clear

tab time,gen(time_)
gen did1 = treat*time_1
gen did2 = treat*time_2
gen did3 = treat*time_3
gen did4 = treat*time_4
gen did5 = treat*time_5
gen did6 = treat*time_6
gen did7 = treat*time_7
gen did8 = treat*time_8
gen did9 = treat*time_9
gen did10 = treat*time_10
gen did11 = treat*time_11
gen did12 = treat*time_12
gen did13 = treat*time_13
gen did14 = treat*time_14
gen did15 = treat*time_15
gen did16 = treat*time_16
gen did17 = treat*time_17
gen did18 = treat*time_18
gen did19 = treat*time_19
gen did20 = treat*time_20
 
reghdfe y  did1-did9 did11-did20   x , absorb(id time) vce(cluster id)

coefplot,  keep(did*)  ///
   vertical recast(connect) color(gs0) ///
   yline(0, lp(solid) lc(gs0) lw(thin)) xline(10, lp(solid) lc(gs0) lw(thin))  ///
   ytitle('估计系数') ylabel(-1(0.5)2, format(%6.1f))                      ///
   xtitle('时期') xlabel(1 5(5)20, nogrid) ///
   text(-0.75 5 '{it:F} = 0.55  {it:p} = 0.84') ///
   ciopts(recast(rline) lc(gs0) lp(dash) lw(thin)) scale(1.2)  xscale(titlegap(tiny))   

其绘制的图形如下所示:

图片从上述code可以看到,这里我们使用了第10期作为基准。但是图示中不能看出到底使用的哪一期作为基期。部分学者通过定横坐标修改的方式,在一定程度上可以让读者清楚使用的哪一期为参考。比如,将横坐标标为1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,可以看到缺少了10,可以猜测作者是以第10期为基期。

3. 生成有基期的平行趋势图

这一部分是完全使用子尧师兄提供代码,代码如下:

use data\simu_data, clear
reghdfe y c.treat##ib10.time  x , absorb(id time) vce(cluster id)
coefplot, baselevels omitted ///
        keep(*.time#c.treat)  ///
   vertical recast(connect) color(gs0) ///
   yline(0, lp(solid) lc(gs0) lw(thin)) xline(10, lp(solid) lc(gs0) lw(thin))  ///
   ytitle('估计系数') ylabel(-1(0.5)2, format(%6.1f))                      ///
   xtitle('时期') xlabel(1 5(5)20, nogrid) ///
   text(-0.75 5 '{it:F} = 0.55  {it:p} = 0.84') ///
   ciopts(recast(rline) lc(gs0) lp(dash) lw(thin)) scale(1.2)  xscale(titlegap(tiny))     

代码非常简洁,其生成的图形如下:

图片

毫无疑问,这张图比上一张好看且实用。这张图的代码读者可自行琢磨,尤其是对c.treat##ib10.timeomitted的理解。自行理解清楚了,下次应该也就会画了。

主要参考文章

[1]黄炜,张子尧,刘安然.从双重差分法到事件研究法[J/OL].产业经济评论,2022(02):1-18.

[2]Andrews, Michael, How Do Institutions of Higher Education Affect Local Invention? Evidence from the Establishment of U.S. Colleges,(Conditionally Accepted, American Economic Journal: Economic Policy,2022)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多