您的位置 首页 > 德语词汇

stacked是什么意思?用法、例句(【Stata 18新功能】堆叠DID(stacked DID)及其应用)

大家好,今天给各位分享stacked是什么意思?用法、例句的一些知识,其中也会对【Stata 18新功能】堆叠DID(stacked DID)及其应用进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!

1.Cunningham,CausalInference:TheMixtape,YalePress,2021

2.Baker,Andrew.Difference-in-DifferencesMethodology,2019

stacked是什么意思?用法、例句(【Stata 18新功能】堆叠DID(stacked DID)及其应用)

3.CoadyWing,SethM.Freedman,andAlexHollingsworth.StackedDifference-in-Differences,NBERWorkingPaperNo.32054,2024

交叠处理下,异质性处理效应使得TWFE有偏,很多新的估计量已经出现了。

堆叠DID(stackeddid)是应对交叠处理偏误的一种方法。近些年,在应用研究中广泛采用,例如,Cengizetal.,2019;DeshpandeandLi,2019;Buttersetal.,2022;CallisonandKaestner,2014。我对堆叠DID产生兴趣是江西财大的王岳龙老师经常给我讲授他的研究设计思想,其实就是堆叠DID,所以我很喜欢跟他交流。堆叠DID给我带来的最大感受就是它太“透明”了,回归就是reg而已。在得不到trueeffect,经验研究者们只能尽量接近真实处理效应,在这条路上,“透明性”也是经验研究最大的护身符。这是最近Twitter上DID圈子里讨论的“DID正在逐渐死去”,因为新DID又带来了太多假设,让DID都快变成“黑箱”了。

回到堆叠DID,例如Cengizetal.(2019)估计了最低工资变化对低收入劳动的影响,基于美国1979-2016年的138次州水平的最低工资变化,采用DID。在附录中,Cengizetal.(2019)指出,加总OLS估计的DID估计量会存在一些问题。作为稳健性检验,作者分别估计了每个事件的单个处理效应,并做出分布图。

作者创建了138个最低工资变化事件的处理地区数据集(将总的数据集分成不同的子集),其中,包括对应事件地区和所有“干净的”控制地区(在估计事件时间窗口还没有发生最低工资变化的州)的结果变量和控制变量。对于每个事件,作者都跑一个单一处理个体的DID:

然后,Cengizetal.(2019)画出所有处理效应的分布,其中,置信区间使用FermanandPinto(2022)的异方差稳健聚类余值bootstrap方法(因为在每个DID回归中,只有单一处理个体)。Cengizetal.(2019)也将每个事件数据集堆叠在一起来计算平均处理效应。正如作者指出,堆叠DID用更加严格的标准来筛选控制组,且对交叠处理的异质性处理效应偏误问题更加稳健。依靠堆叠事件,该方法等价于事件同时发生的情形,因此,防止了交叠处理的负权重问题(Baker,2019)。

也就是说,堆叠DID对每个有效的处理事件(子样本,排除“后处理vs先处理”的比较)都构造一个子样本数据集,然后对子样本数据集跑DID回归。

JoshuaBleiberg基于Cengizetal.(2019)的文章写了一个stata命令stackedev,我们用AsjadNaqvi的模拟数据来看看这个命令的用法:

*模拟数据\nclear\n\nlocalunits=30\nlocalstart=1\nlocalend\t=60\n\nlocaltime=`end'-`start'+1\nlocalobsv=`units'*`time'\nsetobs`obsv'\n\negenid\t=seq(),b(`time')\negent\t=seq(),f(`start')t(`end')\t\n\nsortidt\nxtsetidt\n\n\nsetseed20211222\n\ngenY\t\t\t=0\t\t//outcomevariable\t\ngenD\t\t\t=0\t\t//interventionvariable\ngencohort=.\t//treatmentcohort\ngeneffect=.\t\t//treatmenteffectsize\ngenfirst_treat=.\t\t//whenthetreatmenthappensforeachcohort\ngenrel_time\t=.//time-first_treat\n\nlevelsofid,local(lvls)\nforeachxoflocallvls{\n\tlocalchrt=runiformint(0,5)\t\n\treplacecohort=`chrt'ifid==`x'\n}\n\n\nlevelsofcohort,local(lvls)\nforeachxoflocallvls{\n\t\n\tlocaleff=runiformint(2,10)\n\t\treplaceeffect=`eff'ifcohort==`x'\n\t\t\t\n\tlocaltiming=runiformint(`start',`end'+20)\t//\n\treplacefirst_treat=`timing'ifcohort==`x'\n\treplacefirst_treat=.iffirst_treat>`end'\n\t\treplaceD=1ifcohort==`x'&t>=`timing'\n}\n\nreplacerel_time=t-first_treat\nreplaceY=id+t+cond(D==1,effect*rel_time,0)+rnormal()\n\n\n\n//generateleadsandlags(usedinsomecommands)\n\nsummrel_time\nlocalrelmin=abs(r(min))\nlocalrelmax=abs(r(max))\n\n\t//leads\n\tcapdropF_*\n\tforvalx=2/`relmin'{//dropthefirstlead\n\t\tgenF_`x'=rel_time==-`x'\n\t}\n\n\t\n\t//lags\n\tcapdropL_*\n\tforvalx=0/`relmax'{\n\t\tgenL_`x'=rel_time==`x'\n\t}\n\t\n\t\n//generatethecontrol_cohortvariables(usedinsomecommands)\n\ngennever_treat=first_treat==.\n\nsumfirst_treat\ngenlast_cohort=first_treat==r(max)//dummyforthelatest-ornever-treatedcohort\n\n\n//generatethegvarvariabls(usedinsomecommands)\ngengvar=first_treat\nrecodegvar(.=0)\n\nxtlineY,overlaylegend(off)\n\n\n

image.png

*安装命令\nsscinstallstackedev,replace\n\nhelpstackedev\n\n*运行堆叠DID\nstackedevYF_*L_*,cohort(first_treat)time(t)never_treat(never_treat)unit_fe(id)clust_unit(id)\n\nevent_plot,default_lookgraph_opt(xtitle("相对事件时间")ytitle("平均处理效应")xlabel(-10(1)10)///\n\t\ttitle("stackedev"))stub_lag(L_#)stub_lead(F_#)trimlag(10)trimlead(10)together\n\n

image.png

Cengizetal.(2019)和DeshpandeandLi(2019)用“干净的”控制组来构建堆叠数据集,但是会存在事件研究估计系数的样本不平衡的问题,这可能会产生样本结构变化,进而不可比,使得事件研究系数没有因果含义。Buttersetal.(2022)用了干净的控制组,也施加了结构平衡的限制。CallisonandKaestner(2014)用两个事件时间的堆叠数据集,并用基准期的平均结果来匹配处理组和控制组。

此外,Cengizetal.(2019)报告的标准误实在group×sub-event层面聚类,CallisonandKaestner(2014)、DeshpandeandLi(2019)和Buttersetal.(2022)则聚类在group层面。

这些都只是应用研究文献,并没有给出堆叠DID估计量的识别公式。Wingetal.(2024)正式给出了堆叠DID估计量的正式推导,并提出了一种加权方法来计算平均处理效应。而且应用型文献的回归方程仅仅包括group×sub-event、time×sub-event固定效应,并没有使用饱和式堆叠回归方程。

Wingetal.(2024)提出了一类构建堆叠数据集的包容性条件来删节事件研究窗口,以确保每个子事件(sub-event)数据集处理前后的时期数是平衡的。然后,作者提出了一种新方法来估计总的平均处理效应(ATT),这种单一堆叠回归法允许使用传统的方法来进行统计推断。

Wingetal.(2024)认为,他们的删节总ATT(trimmedaggregateATT)有三个优势:(1)所有的估计量都有一致的因果理解,因为它是一系列平衡因果效应的凸结合;(2)由于平均处理效应来自于删节的处理效应,因此,事件时间上的系数裱花反映的就是处理效应动态,而不是每个事件时间上的结构变化;(3)在DD假设下,处理前的系数应该等于0。因为堆叠数据的结构在事件时间上是非常稳定的,处理前处理效应系数的值就是差异化的处理前趋势,这可以理解成处理前共同趋势或者预期。

我们用Wingetal.(2024)提供的例子来看看他们的删节堆叠DID估计量:美国ACA医疗补助计划扩围对19-60岁的成年人未保险率的影响。数据集跨度2008-2021年,美国51个州的面板数据,共714个样本。

***********************************************************\t\t\t\n*GettingStartedWithStackedDID\n*Aside-by-sidecomparisonofRandStatacode\n\n*AUTHOR:CoadyWing,AlexHollingsworth,andSethFreedman\t\n***********************************************************\t\n//Loadthedata\n\nclear\ncd"/Users/xuwenli/Library/CloudStorage/OneDrive-个人/DSGE建模及软件编程/教学大纲与讲稿/应用计量经济学讲稿/应用计量经济学讲稿与code/DID与SC/"\n\t\t\nimportdelimited"acs1860_unins_2008_2021.csv",clear\n\nsum\n\ntabadopt_year\n\n

其中,unins是结果变量——19-60岁的成年人没有参加健康保险的比例;adopt_year是初次实施ACA计划的年份;还未实施ACA计划的州state用NA表示。如下图所示,ACA扩围计划分别在2014、2015、2016、2019、2020、2021年实施。

Wingetal.(2024)指出,堆叠DID最关键的是要重组数据集,从原始面板数据中重新形成“干净”控制组的子数据集。因此,作者提供了一个stata命令create_sub_exp来重塑堆叠DID所需的子数据集。。需要注意的是,作者并没有以.ado的形式呈现上述命令。如果有需要,可以给我发邮件。我跟Wing邮件交流的时候,发现的他们的手册写得并不是很清楚,初次使用可能会报错。我自己的步骤是:

①首先,将Wingetal.(2024)的“create_sub_exp()”函数命令copy到stata的dofile中,然后保存成create_sub_exp.ado;

②将create_sub_exp.ado放置在stata/ado/personal文件夹中

create_sub_exp,\ntimeID()groupID()adoptionTime()focalAdoptionTime()kappa_pre()kappa_post()\n\ntimeID:时间变量groupID:个体变量adoptionTime:每个个体的处理时点,对于从未处理的个体是NA;focalAdoptionTime:用户声明的子事件的处理时点;kappa_pre:用户声明的处理前时期;kappa_post:用户声明的处理后时期;

我们知道,堆叠DID就是按照每个事件时间重新构建数据子集。下面,来看看这个命令重塑的ACA医疗扩围计划的数据子集。例如,我们先看看2014年实施的ACA计划的子集。

/*Createsub-experimentdataforstack*/\n//Makingsub-experimentaldatasets\n*Savedataset\npreserve\n\n*Runthisfunctionwithfocalyear2014\ncreate_sub_exp,///\ntimeID(year)///\ngroupID(statefip)///\nadoptionTime(adopt_year)///\nfocalAdoptionTime(2014)///\nkappa_pre(3)///\nkappa_post(2)\n\n*Opentempdatasetcreatedwithfunction\nusetemp/subexp2014.dta,clear\n\n*Summarize\nsumstatefipyearadopt_yearuninstreatpostevent_timefeasiblesub_exp\n\n*Restoredataset\nrestore\n\n\n

从上述结果,我们可以看出,2014年处理时点的子样本集有276个样本。这个时候,我们就可以跑DID回归了:

*twfe\nxtsetstatefipyear\ngend=treat*post\nreghdfeuninsd,ab(statefipyear)cluster(statefip)\n

从上述结果可以看出,2014年处理时点的数据子集的DD估计系数为-0.019,在95%的置信水平上显著。意味着ACA扩围计划降低了未保险比例,统计上显著。

实践中,我们可能对单一数据子集并不感兴趣。我们想要所有的单一处理时点的数据子集堆叠在一起。下面,用一个stata循环来运行上述命令得到每一个实施年份的数据子集。然后,将单一数据子集堆叠在一起,形成一个“垂直”结合的数据集stacked_dtc。注意,在这个数据集中并不包含2020和2021两年,因为Wingetal.(2024)在删节的时候,选取了处理前3期(-3,-2,-1),处理后3期(0,1,2),而2020和2021处理后并没有3期数据可用,因此没有构造它们的数据子集。这就是Wingetal.(2024)提出的“包容性标准”——让事件研究设计不存在结构性变化,即是结构性平衡的

//Buildthestackofsub-experiments\n//createthesub-experimentaldatasets\n\nlevelsofadopt_year,local(alist)\ndi"`alist'"\nqui{\n//Loopovertheeventsandmakeadatasetforeachone\nforeachjofnumlist`alist'{\n//Preservedataset\npreserve\n\n//runfunction\ncreate_sub_exp,///\ntimeID(year)///\ngroupID(statefip)///\nadoptionTime(adopt_year)///\nfocalAdoptionTime(`j')///\nkappa_pre(3)///\nkappa_post(2)\n\n//restoredataset\nrestore\n}\n\n//Appendthestackstogether,butonlyfromfeasiblestacks\n*Determineearliestandlatesttimeinthedata.\n*Usedforfeasibilitychecklater\nsumyear\nlocalminTime=r(min)\nlocalmaxTime=r(max)\nlocalkappa_pre=3\nlocalkappa_post=2\n\ngenfeasible_year=adopt_year\nreplacefeasible_year=.ifadopt_year<`minTime'+`kappa_pre'\nreplacefeasible_year=.ifadopt_year>`maxTime'-`kappa_post'\nsumfeasible_year\n\nlocalminadopt=r(min)\nlevelsoffeasible_year,local(alist)\nclear\nforeachjofnumlist`alist'{\ndisplay`j'\nif`j'==`minadopt'usetemp/subexp`j',clear\nelseappendusingtemp/subexp`j'\n}\n\n//Cleanup\n*erasetemp/subexp`j'.dta\n}\n*Summarize\nsumstatefipyearadopt_yearuninstreatpostevent_timefeasiblesub_exp\n\n

image.png

*Treated,control,andtotalcountbystack\npreserve\nkeepifevent_time==0\ngenN_treated=treat\ngenN_control=1-treat\ngenN_total=1\ncollapse(sum)N_treatedN_controlN_total,by(sub_exp)\nlistsub_expN_treatedN_controlN_totalin1/4\n/*\nsumuptreatifevent_time==0,s(N)\nstacked_dtc[event_time==0,\n.(N_treated=fsum(treat),\nN_control=fsum(1-treat),\nN_total=.N\n),\nby=sub_exp][order(sub_exp)]\n*/\nrestore\n\n

上表展示了堆叠数据中包含四个处理时点:2014、2015、2016、2019。且2014年有28个处理组,2015年有3个,2016年有2个,2019年也有2个。与此对比,2014、2015、2016年包含18个干净的控制组,2019年包含11个。

其实,我们此时可以分别利用上述4个数据子集来跑DID回归,得到TWFEDID估计量,这些估计量都是对应处理年份ACA的平均处理效应,大家可以自己去试试。

但是,我们可能更关心所有的处理时点的总的平均处理效应,也就是上述4个处理事件的ACA总的平均处理效应。这个时候,可以使用Wingetal.(2024)给出的另一个stata命令compute_weights。这个命令可以构造恰当的权重来加权堆叠DID回归,也就是说,这个命令利用上述构建的堆叠数据集来计算处理组和控制组的样本权重。命令格式:

compute_weights,\ntreatedVar(string)///\neventTimeVar(string)///\ngroupID(string)///\nsubexpVar(string)\n\ntreatedVar:处理变量,在给定数据子集中,个体是否作为处理组;eventTimeVar:处理时点groupID:个体变量subexpVar:每个事件时间变量

//Usecompute_weights()tocomputethestackedweights\ncompute_weights,///\ntreatedVar(treat)///\neventTimeVar(event_time)///\ngroupID(statefip)///\nsubexpVar(sub_exp)\n\n*Summarize\nbysub_exp:sumstack_weightiftreat==0&event_time==0\n\n

得到权重后,我们可以利用堆叠数据集来跑堆叠回归,得到总的ACA处理效应:

//Estimatethestackedregression\n//Createdummyvariablesforevent-time\ncharevent_time[omit]-1\nxii.event_time\n\n//Runregression\nquireghdfeuninsi.treat##i._I*[aw=stack_weight],cluster(statefip)absorb(treatevent_time)\neststoweight_stack\n\n//Showresults\nesttabweight_stack,keep(1.treat#1*)se\n\n//eventstudyplot\ncoefplot,yline(0)verticaldrop(_cons)\n

image.png

END,本文到此结束,如果可以帮助到大家,还望关注本站哦!

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023