本篇博文主要是对断点回归的一些学习和总结~
学习材料如下:
1 断点回归设计RDD分类与操作案例
2 RDD断点回归, Stata程序百科全书式的宝典
3 断点回归设计的前沿研究现状, RDD
4 让“跳跃”更有意义:断点回归设计(RDD)
5 连玉君老师教程: Stata: 断点回归 (RDD) 教程
6 怎么用通俗的语言解释断点回归?它与DID的区别是什么
7 Watering Down Environmental Regulation in China,Guojun He, Shaoda Wang, Bing Zhang,The Quarterly Journal of Economics, Volume 135, Issue 4, November 2020, Pages 2135–2185,
重点推荐学习材料1 3 5 7,7是一篇2020年在QJE发表的一篇论文,个人认为这篇论文思路很清楚,内容很丰富,值得学习!
因果分析与政策效应评估是经济分析最为关注的核心问题,然而我们运用计量模型进行因果分析的总是囿于在于模型的内生性问题。
常用的解决原理是借助准自然实验 (quasiexperiment) 的思想评估不同政策的处理效应, 试图获得一致 (consistent) 或者无偏 (unbiased) 估计量。
进而发展出的方法有 工具变量 (Instrumental variables) 、匹配和加权估计法 (matching and reweighting) 、倍差法 (difference-in-difference) 和断点回归设计 (regression discontinuity design)。
对于断点回归(RDD),和其他方法相比, 学术界普遍认为运用断点回归设计更接近准自然实验, 估计的结果更加准确,原因在于其设计思想。
设计思想:其基本思想是存在一个连续变量, 该变量能决定个体在某一临界点两侧接受政策干预的概率, 由于X在该临界点两侧是连续的, 因此个体针对X的取值落入该临界点任意一侧是随机发生的, 即不存在人为操控使得个体落入某一侧的概率更大, 则在临界值附近构成了一个准自然实验。
**举例1:**在一条河流随机设置一个水质监测点,设置水质监测点10公里范围内的以上为上游,以下为下游。可以以RDD研究在水质监测点的上下游对企业绩效的影响。因为在10公里范围内,可以默认为企业的其他因素相似(当然也会控制一些固定效应)
**举例2:**一本线附近,刚刚考上和差一点考上可以设计RDD模型来研究考上一本对未来收入的影响。因为在分数范围内,可以默认为考生的其他方面相似(当然也会控制一些特征)
由此, 近年来越来越多的实证文献依赖断点回归设计进行政策效应评估。
断点回归的基本思想是基于连续变量x随机划定组别,因而我们一般将该==连续变量X称为分组变量 (assignment variable) ==。
按照在断点处个体得到处理效应概率的变化特征可以分为两种类型:一种类型是精确断点回归设计 (sharp regression discontinuity design, 以下简称SRD) , 和模糊断点回归设计 (fuzzy regression discontinuity, 以下简称FRD) 。
来自 断点回归设计RDD分类与操作案例
(1)举例引入
考察上大学对工资收入的影响。假设上大学与否(Di)完全取决于由高考成绩xi是否超过500分:
(1)Di 是 关于 x的确定函数,与其他无关,独立于工资收入。
(2)无法采用PSM+DID,因为重叠假定不满足,所有处理组都大于500分,所有控制组都小于500分。
(3)对于高考成绩为498,499,500,或501的考生,可以认为他们在各
方面(包括可观测变量和不可观测变量)都没有系统差异。
(4)他们高考成绩的细微差异只是由于“上帝之手”随机抽样的结果,导致成绩为500或501的考生上大学(进入处理组),而成绩为498或499的考生落榜(进入控制组)。
(5)因此,由于制度原因,仿佛对高考成绩在小领域500-s,500+s]之间的考生进行了随机分组,故可视为准实验( quasi experiment)。
(6)由此,由于存在随机分组,故可一致地估计在x=500附近的局部平均处理效应(Local Average Treatment Effect,LATE)
(2)模型设计
一般地, 假设断点为某常数c,而分组规则为:
假设在实验之前,结果变量y与x之间存在如下线性关系: .
假设处理效应为正,则y; 与x之间的线性关系在x=c处就存在一个向上跳
跃(jump)的断点。
但通常为了估计跳跃点的小于,我们会减去c
由此,断点回归可视为“局部随机试验”(Local randomized experiment);可通过考察协变量在断点两侧的分布是否有差异来检验随机性。
注意:但断点回归仅推断在断点处的因果关系,不能推广到其他样本值,故外部有效性受局限。
存在问题:
1)使用方程(1)估计精确断点回归,存在两个问题:
➢ 如果回归函数包含高次项,比如二次项(x-c)2, 则会导致遗漏偏差。
➢ 既然断点回归是局部的随机实验,则原则上只应使用断点附近的观测
值,但方程(1)却使用了整个样本。
2)存在内生分组危险。如果个体知道分组规则,可能会通过自身努力而完全控制分组变量。因而,我们常用的解决方法是在断点处观察x的分布是否均匀。除此,也可检验协变量的连续分布。
常用汇报操作
1)分别汇报三角核和矩形核的局部线性回归结果(后者等价于线性参数回归
2)分别汇报使用不同带宽的结果(比如,最优带宽及其二分之一或两倍带宽)
3)分别汇报包含协变量与不包含协变量的情形
4)进行模型设定检验,包括检验分组变量与协变量的条件密度是否在断点处连续
模糊断点回归的特征是,在断点x=c处,个体得到处理的概率从a跳跃到b,其中0c,也不一-定得到处理,但得到的处理的概率在x=c处有不连续的跳跃。本质上有点类似于工具变量法。
(1)举例引入:
高考成绩上线并不能完全保证上大学,能否上大学还取决于填报志愿,甚至有些上线考生放弃上大学 的机会;而即使成绩未上线,但也可能因某种特长而得到加分,从而得到上大学的机会。上大学的概率确实在分数线的位置上有一个不连续的跳跃。
在模糊断点的情况下,处理变量D不完全由分组变量x所决定。
(2)模型设计
一般来说,影响处理变量x的其他因素也会影响结果变量y,导致在
回归方程中处理变量D与扰动项ε相关,存在内生性问题,OLS不一致。
为在模糊 断点的情况下识别平均处理效应,需要引入以下条件独立假定。
估计思路
在对平均处理效应做出估计前,需要对一些关键假设做出检验(上面有提到):
(1) △D (X=c) ≠0, 也就是检验处理变量在断点c处是否存在跳跃(可通过绘图确认);
(2) △D (X≠c) =0以及△Y (X≠c) =0, 检验处理变量D和结果变量Y在断点以外的其他点不存在跳跃
(3) △W (X=c) =0, W代表影响结果变量的控制变量(协变量), 该检验表示检验控制变量(协变量)在断点处不存在跳跃;
(4) △f (X=c) =0, f代表概率密度函数, 该检验表示检验分组变量在断点处的概率密度函数是连续的, 也就是在断点附近, 个体不能操控X的取值, 个体落入断点的左侧或右侧是随机发生的;
(5) τSRD≠0或者τFRD≠0, 检验平均处理效应不等于0。
估计方法
估计方法分为非参数化方法和参数化方法对平均处理效应系数进行估计,。
(1)非参数化方法主要是指局部线性回归方法 (local linear regression) ;
(2)参数化方法主要是指局部多项式回归 (local polynomial regression) 。
在局部线性回归中, 选取合适的带宽是至关重要的, 带宽的选择是在准确和偏差之间进行权衡。
那么带宽是什么?带宽就是断点邻域大小的选择,简单理解就是在该领域考察是否存在跳跃。一般来说,如果带宽选择很大则可供估计的观察值越多, 这将使得估计结果更准确, 但是平均处理效应估计值的偏差将越大;另一方面, 如果带宽选择很小, 准确性降低但偏差减小。
局部多项式回归的多项式, 可以是一次、两次、三次甚至更高阶, 可以采取不同的多项式形式对式 进行估计, 比较不同回归方程形式下τ的估计结果, 进而检验估计结果的稳健性/
1)区别在前面有提及到一点,就是数据的可重叠性不满足。
举例,考察上大学对工资收入的影响。假设上大学与否(Di)完全取决于由高考成绩xi是否超过500分:无法采用PSM+DID,因为重叠假定不满足,所有处理组都大于500分,所有控制组都小于500分。
(2)探究的分组样本属性不同,观点来自知乎Luciano
怎么用通俗的语言解释断点回归?它与DID的区别是什么
RD的目的是选取其他特征相似的组,考察临界值区间上下不同。
例如,考察进入清华与否对于收入的影响。 考试成绩为687的人无法上清华大学,而考试分数为689的人课可以进去。仅仅2分之差,这两类人的基本能力其实没什么差别。 两组人,围绕着688分的分界线,对于研究工资差异都具有较高的内部效度,因为两者之间的唯一区别是是否进入清华。其他一切都是不变的。把这个理念延伸一下 控制其他变量,数据分为1)688以下, 2)688以上两组。 回归拟合线应该斜率相近, 但是截距有明显差别,截距项可以理解为入学带来收入差异。
DID的目的是比较两组存在差异的群体,但是该差异的影响必须是随着时间变化是恒定的。
比如处理前A2010 ,处理后A2020; 处理前 B2010,处理后 B2020. 所以(A2010 - B2010 )=m 就是所谓的first difference. 这里m就是A和B组预先存在的差别。 然后( A2020 - B2020)=n , 这里就是second difference, 其中n包含了处理的效应Treatment 和预先差别m,最后, n-m= treatment效果。
这就是difference in difference. RD需要数据更少,主要是考虑临界值附近的影响。 DID需要panel data面板数据,并且更容易广泛使用。
(1)rd
rd outcomevar [treatmentvar] assignmentvar [if] [in] [weight] [, options]
其中,“outcomevar”为结果变量,“treatmentvar”为处理变量,assignmentvar为分组变量。
选择项“z0(real)”用来指定断点位置,默认值为“z0(0)”,即断点为原点。
选择项“mbw(numlist)”用来指定带宽,默认值为“mbw(50 100 200)”。
选择项“graph”表示根据所选的每一 带宽,画出其局部现行回归图。
选择项“bdep”表示通过画图来考察断点回归估计量对带宽 的依赖性。
选择项“oxline”表示在此图的默认带宽上画一条直线,以便识别。
选择项“Kernel(rectangle)”表示使用矩形核,默认使用三角核。
选择项“cov(varlist)”用来指定加入局部线性回归的协变量。
选择项“x(varlist)”表示检验这些协变量是否在断点处有跳跃(估计其跳跃值和显著性):
还有cluster(varlist) 等选项,可以通过stata help rd查看
举例:传统上,民主党倾向于大政府,故一个选区如果有民主党众议员,则该议员可能为该选区争取更多的联邦支出。然而,直接对二者进行回归可能存在遗漏变量问题或双向因果问题。为此,使用民主党候选人的得票率作为分组变量,以0.5作为断点(在两党政治中,得票率大于或等于0.5则当选,反之落选),进行断点回归。其中结果变量为lne(选区联邦开支的对数)、分组变量为d(民主党候选人得票率减去0.5)、处理变量win(民主党候选人当选),以及一系列协变量。
实现1: rd lne d, mbw(100)
实现2(添加处理变量win): rd lne win d, mbw(100)
实现3(添加协变量):rd lne d, mbw(100) cov(i votpop black blucllr famer fedwrkr forbornmanuf unemplyd union urban verterans)
(2)rdrobust
rdrobust depvar runvar [if] [in] [, c(cutoff) p(pvalue) q(qvalue) deriv(dvalue) fuzzy(fuzzyvar [sharpbw]) covs(covars) kernel(kernelfn) weights(weightsvar) h(hvalueL hvalueR) b(bvalueL bvalueR) rho(rhovalue) scalepar(scaleparvalue) bwselect(bwmethod) scaleregul(scaleregulvalue) vce(vcemethod) level(level) all]
其中 depvar is the dependent variable
runvar is the running variable (also known as the score or forcing variable).
c(cutoff)指定RD跳跃点。 默认值为c(0)。
p(pvalue)指定用于构造点估计量的局部多项式的阶数。 默认值为p(1)(局部线性回归)。 (多项式选择与否)
q(qvalue)指定用于构造偏差校正的局部多项式的阶数。 默认值为q(2)(局部二次回归)。
Fuzzy(fuzzyvar [sharpbw])指定用于实现模糊RD估计的处理状态变量(如果还指定了deriv(1),则指定 fuzzy kink RD 。 默认为 sharp RD 设计。 如果设置了Sharpbw选项,则使用针对Sharp RD模型的带宽选择过程执行模糊RD估计。
如果阈值的任一侧都完全符合要求,则将自动选择此选项。
covs(covars) 、 kernel(kernelfn)、 weights(weightsvar) 同上
h(hvalueL hvalueR)指定要在跳跃点的左侧和右侧分别使用的主带宽h。 如果仅指定一个值,则在两侧都使用该值。 如果未指定,则带宽h由伴随命令rdbwselect计算。
b(bvalueL bvalueR)指定偏置带宽b,分别在截止点的左侧和右侧使用。 如果仅指定一个值,则在两侧都使用该值。 如果未指定,则带宽b由伴随命令rdbwselect计算。
bwselect(bwmethod)指定要使用的带宽选择过程。 默认情况下,除非指定rho,否则它将同时计算h和b,在这种情况下,它将仅计算h并设置b = h / rho。
Examples
Example: Cattaneo, Frandsen, and Titiunik (2015) incumbency data
Setup
. use rdrobust_senate.dta
Robust RD estimation using MSE bandwidth selection procedure
. rdrobust vote margin
Robust RD estimation with both bandwidths set to 15
. rdrobust vote margin, h(15)
Other generic examples (y outcome variable, x running variable, t treatment take-up indicator):
Estimation for sharp RD designs
. rdrobust y x, deriv(0)
Estimation for sharp kink RD designs
. rdrobust y x, deriv(1)
Estimation for fuzzy RD designs
. rdrobust y x, fuzzy(t)
Estimation for fuzzy kink RD designs
. rdrobust y x, fuzzy(t) deriv(1)
(3)rdcv
运行速度有点慢,所以这里不详细展开了
rdcv depvar indepvar [weight] [if] [in] , (threshold(numeric) | notrd) [options]
这里学习的是连玉君老师关于RDD教程: Stata: 断点回归 (RDD) 教程,可点击原文学习一下哟!推荐学习~
**************************
* 生成模拟数据
**************************
/*
1 生成一份模拟数据,并保存为 RDD_simu_data0
2 生成的数据中,z1 和 z2 为控制变量。 y1 为结果变量(outcome variable)。
3 x为分配变量(assignment vaiable)。分配点(cutoff point)设定为 0.5 ,从而x大于0.5 的为实验组,小于0.5的为对照组。
4 此外,在RDD检验中,我们通常还会对分配变量进行去中心化处理,即用分配变量减去分配点值。
5 如本文中,令 xc=x-0.5 。进而 xc 大于 0 的位实验组,反之为对照组。
*/
clear all
set obs 4000
set seed 123 // 保证生成的随机数 每次都一样 保持数据的可重复性
gen x = runiform() //分配变量 0-1变量的均匀分布
gen xc = x-0.5 //分配变量去中心化
gen e = rnormal()/5 // noise
gen z1 = rnormal()*0.5 //控制变量
gen z2=1+3*invnormal(uniform())+sin(x*5)/3+e //另一个控制变量
gen T=0
replace T=1 if x>0.5 //treatment
gen g0 = 0 + 3*log(x+1) + sin(x*6)/3
gen g1 = T + 3*log(x+1) + sin(x*6)/3
gen y1 = g1 + 0.5*z1 +0.3*z2+ e // outcome vaiable,with cutoff effect
gen y0 = g0 + 0.5*z1 +0.3*z2+ e // outcome variable, without cutoff effect
label var y1 "Outcome variable (y)"
label var y0 "Outcome variable (y)"
label var x "Assignment variable (x)"
label var xc "Centered Assignment variable (x-c)"
label var T "T=1 for x>0.5, T=0 otherwise"
drop e g*
save "RDD_simu_data0.dta", replace //保存一份数据以备后用
/*
使用 RDD 方法检验时,首先要确定结果变量在分配点存在跳跃现象,也即存在断点效应。可以用散点图来观察。
*/
use "RDD_simu_data0.dta", clear
twoway (scatter y0 xc, msymbol(+) msize(*0.4) mcolor(black*0.3)) , title("无断点")
graph save y0, replace
twoway (scatter y1 xc, msymbol(+) msize(*0.4) mcolor(black*0.3)) , title("有断点")
graph save y1, replace
graph combine y0.gph y1.gph, row(1)
//存在两个问题:一是样本太多时不够直观,二是实际分析时中跳跃现象可能不那么清晰。
/*
利用拟合方法,对分配点左右分别拟合,通过==观察两侧拟合线的的差异==来更容易推测跳跃现象是否发生
RDD分析里提供了rdplot命令处理这项工作
*/
//分别列出了利用散点图、 rdplot 命令 + 线性拟合、 rdplot命令 + 二阶多项式拟合图和rdplot命令 + 三阶多项式拟合图的结果
use "RDD_simu_data0.dta", clear
twoway (scatter y1 xc, msymbol(+) msize(*0.4) mcolor(black*0.3)), title("散点图")
graph save scatter.gph, replace
rdplot y1 xc, c(0) p(1) graph_options(title(线性拟合)) // 线性拟合图 y1为outcome vaiable,with cutoff effect
graph save rd1, replace
rdplot y1 xc, c(0) p(2) graph_options(title(二次型拟合))//二次型拟合图 y1为outcome vaiable,with cutoff effect
graph save rd2, replace
rdplot y1 xc, c(0) p(3) graph_options(title(三次型拟合))//三次型拟合图 y1为outcome vaiable,with cutoff effect
graph save rd3, replace
graph combine scatter.gph rd1.gph rd2.gph rd3.gph
**************************
* 局部线性回归
**************************
/*
1 使用局部线性回归法,是假定在断点邻域中的处理效应为线性,通过在左右两侧邻域分别进行线性回归并比较两侧回归系数差异来进行识别
2 局部回归检验的一个重要环节在于断点邻域大小的选择,也即 RDD 分析里带宽选择 (bandwidth selection) 的权衡问题
3 因为带宽越大,则意味着有越多的样本被纳入检验中,参数估计更准确,但也意味着样本随机性要求越难满足,内生性问题可能更严重
4 本文中断点xc的邻域为 ([xc-h1,xc+h2]) , h1 和 h2 分别为左右两侧带宽。h1和h2可以相等,也可以不等
5 在断点分析中,可进行局部线性断点回归的命令有 rd、rdrobust 和 rdcv 三个命令。这三个都会自动给出该命令下最优带宽。
*/
//由于rdc命令回归较为耗时,本文仅随机抽取模拟数据中10%的观察值来演示。
use "RDD_simu_data0.dta", clear
set matsize 2000
set seed 135
sample 10 //随机抽取10%的观察值
rdplot y1 xc, c(0) //检测一下,看看数据特征是否发生明显变化
// 不同局部线性断点回归命令
rd y1 xc, c(0) // 给出最优带宽 同时给出了带宽取最优带宽50%和200%的回归结果
rdrobust y1 xc, c(0) p(1)
rdcv y1 xc, thr(0) deg(1) // 运行过程有点慢
*************************
* 局部多项式回归
**************************
/*
1 线性假设可能会错误估计了断点左右的回归系数,我们可以采取==非线性拟合==的办法进行弥补,即使用局部多项式断点回归方法
2 rd、rdrobust和rdcv 三个命令,同样可以用于局部多项式断点回归分析
*/
use "RDD_simu_data0.dta", clear
rdrobust y1 xc //自动选择阶数
rdrobust y1 xc, p(2) //二阶拟合
rdrobust y1 xc, p(3) //三阶拟合
*
1 对于局部多项式断点回归,关键问题之一在于阶数的选择。
2 利用赤池信息准则 (Akaike Information Criterion,AIC) 和贝叶斯信息准则 (Bayesian Information Criterion,BIC)。
3 选择不同阶数回归中AIC或BIC信息准则小的值。
*/
//单设立一个do文件
*---------------------------------myic-----------------------
program define myic
version 13
qui estat ic
mat a = r(S)
estadd scalar AIC = a[1,5]
estadd scalar BIC = a[1,6]
end
*---------------------------------myic------------------
*-Note: 调用自定义程序myic的方法为选中上述代码,按快捷键 Ctrl+R, 将程序读入内存
use "RDD_simu_data0.dta", clear
set matsize 2000
set seed 135
sample 10 //rdcv回归较为耗时,仅随机抽取10%的观察值来演示。
#d ;
rdcv y1 xc, thr(0) deg(1); myic; est store m1;
rdcv y1 xc, thr(0) deg(2); myic; est store m2;
rdcv y1 xc, thr(0) deg(3) ; myic; est store m3;
#d cr // #d 表示 #delimit
*-对比回归结果
local m "m1 m2 m3"
esttab `m', mtitle(`m') b(%6.3f) t(%6.3f) ///
s(N r2 r2_a AIC BIC) nogap compress
**************************
* 全局多项式回归
**************************
/*
1 全局多项式回归是使用了样本里所有数据来进行多项式回归
2 方法上,等价于局部回归分析里将左右带宽设置为分配变量的最小值和最大值
3 需要注意的是,由于使用了全部样本,全局断点回归分析可能存在较为严重的内生性问题
*/
use "RDD_simu_data0.dta", clear
sum xc
local hvalueR=r(max)
local hvalueL= abs(r(min))
rdrobust y1 xc, h(`hvalueL' `hvalueR') //自动选择阶数
rdrobust y1 xc, h(`hvalueL' `hvalueR') p(2) //二阶拟合
rdrobust y1 xc, h(`hvalueL' `hvalueR') p(3) //三阶拟合
**************************
* 局部平滑性的检验
**************************
/*
1 局部平滑假设,是指除了结果变量,所有所有其它变量在断点附近都不应该存在处理效应,也即没有出现跳跃现象
2 可以利用图形直接观察,也可以将每一个协变量作为安慰剂结果变量 (placebo outcomes) ,使用断点回归方法进行检验
*/
use "RDD_simu_data0.dta", clear
// 图形检验
rdplot z1 xc graph_options(title(z1平滑性检验))
graph save rdz1_smooth, replace
rdplot z2 xc graph_options(title(z2平滑性检验))
graph save rdz2_smooth, replace
graph combine rdz1_smooth.gph rdz2_smooth.gph, title("变量z1 & z2的平滑性检验") // 从图形,似乎是存在跳跃的,但这并不严格,要看回归结果
// 回归检验
rdrobust z1 xc
rdrobust z2 xc
**************************
* 断点的安慰剂检验
**************************
/*
1 稳健性检验的一个自然而然的思路在于选择一个不同于断点的值作为安慰剂断点 (placcebo cutoff points)
2 如果断点回归结果变得不显著,则表明断点的真实性
3 相应代码分别取真实断点两侧 20%、40%、60% 和 80% 样本分位数处作为断点
4 作为对比,我们也放入了真实断点在图形里
*/
use "RDD_simu_data0.dta", clear
sum xc
local xcmax=r(max) //1
local xcmin= r(min)
forvalues i=1(1)4{
local jr=`xcmax'/(`i'+1)
local jl=`xcmin'/(`i'+1)
rdrobust y1 xc if xc>0,c(`jr')
estimates store jl`i'
rdrobust y1 xc if xc<0,c(`jl')
estimates store jr`i'
}
//加上真实断点的回归结果,作为benchmark结果
rdrobust y1 xc ,c(0)
estimates store jbaseline
//输出图形 五个placebo cutoffs 的回归系数都不显著异于0,从而在这些点处不存在处理效应
local vlist "jl1 jl2 jl3 jl4 jbaseline jr4 jr3 jr2 jr1 "
coefplot `vlist' , yline(0) drop(_cons) vertical
**************************
* 驱动变量不受人为控制的检验
**************************
/*
1 不存在人为操控,那么在断点附近样本的数量应该相近,才符合随机性
2 可以用 rddensity 命令来检验断点两侧样本数量是否相近
3 回归结的 p 值为 0.195 ,不能拒绝断点附近两测样本量大致相等的假设
4 知驱动变量不受人为控制的假设满足
*/
use "RDD_simu_data0.dta", clear
rdrobust y1 xc
local h = e(h_l) //获取最优带宽
rddensity xc, p(1) hl(`h') hr(`h')
**************************
* 样带宽选择的敏感性检验
*************************
/*
1 带宽长度会显著影响回归结果,一个稳健的结果要求对带宽长度不那么敏感
2 先通过rdrobust命令提取最优带宽h,然后分别手动设置带宽为 h 的 25%-400% 倍,看回归结果是否仍旧显著
3 图形给出了回归系数和95%的置信区间
*/
use "RDD_simu_data0.dta", clear
rdrobust y1 xc //自动选择最优带宽
local h = e(h_l) //获取最优带宽
forvalues i=1(1)8{
local hrobust=`h'*0.25*`i'
rdrobust y1 xc ,h(`hrobust')
estimates store hrob`i'
}
//输出图形
local vlist "hrob1 hrob2 hrob3 hrob4 hrob5 hrob6 hrob7 hrob8 "
coefplot `vlist' , yline(0) drop(_cons) vertical
**************************
* 样本选择的敏感性检验
**************************
/*
1 由于越接近断点的样本,越有动机去人为操控,我们删除最接近断点的样本,来观察回归是否显著(甜甜圈效应, donut hole approach )
2 如果仍旧存在,说明即使存在人为操控,断点效应仍旧存在
3 分别删除了断点附近 5%,10%,15%,25% 和 30% 的样本,进行了 6 组稳健性检验。图形给出了回归系数和 95% 的置信区间
4 在删除 20% 及以下时,回归结果都保持显著
*/
use "RDD_simu_data0.dta", clear
sum xc
local xcmax=r(max) //1
forvalues i=1(1)6{
local j=`xcmax'*0.05*`i'
rdrobust y1 xc if abs(xc)>`j'
estimates store obrob`i'
}
//输出图形
local vlist "obrob1 obrob2 obrob3 obrob4 obrob5 obrob6 "
coefplot `vlist' , yline(0) drop(_cons) vertical
Watering Down Environmental Regulation in China,Guojun He, Shaoda Wang, Bing Zhang,The Quarterly Journal of Economics, Volume 135, Issue 4, November 2020, Pages 2135–2185
是一篇很经典的RDD检验论文,而且作者研究设计和想法都很新颖,强烈推介阅读学习。
本文基于中国地表水监测系统利用断点回归设计估计了环境规制对企业生产率的影响。水质监测数据对于上级政府评价地方官员至关重要,并且水质监测站只能监测来自上游的排放,地方政府有更强的激励对那些刚好处在监测站上游的企业实施更加严格的排放控制政策。利用这一断点,作者发现处在上游的企业的TFP平均比下游企业低了 27 % 。 基于此估计测算,中国水污染减排计划(2016-2020)将会导致10,000亿元的工业产值损失。
论文数据及代码,作者都提供了!!
************************** Figure 4 RD on TFP *****************************
use "tfp_small_QJE_final.dta",clear
// resid1_tfpop_s 是 Station FE + industry FE absorbed 的TFP GAP
winsor2 resid1_tfpop_s , replace cuts(0.5 99.5) trim
/*
1 绘制了对数TFP(吸收站固定效应和行业固定效应)对“到相应监视站的距离”的图。
2 每个点代表距离范围内公司的平均对数TFP;还显示了它们的90%置信区间。
3 拟合曲线覆盖在图形上,以说明监测站周围的不连续性。
*/
**污染行业
preserve
rdplot resid1_tfpop_s distance_new if neg_ind0==1 & abs(distance_new)<10, p(3) kernel(uni) nbins(7 7) ci(90) ///
graph_options(subtitle("Panel A. TFP in Polluting Industries") legend(off) ytitle(Residualized TFP (log)) xtitle(Distance from Monitoring Station) scheme(plotplainblind))
restore
graph save $figure/F3_Polluting_resid1_tfpop_s, replace
graph export $figure/F3_Polluting_resid1_tfpop_s.png, replace
**非污染行业
preserve
rdplot resid1_tfpop_s distance_new if neg_ind0==0& abs(distance_new)<10, p(3) kernel(uni) nbins(7 7) ci(90) ///
graph_options(subtitle("Panel B. TFP in Non-Polluting Industries") legend(off) ytitle(Residualized TFP (log)) xtitle(Distance from Monitoring Station) scheme(plotplainblind))
restore
graph save $figure/F3_Non_Polluting_resid1_tfpop_s, replace
graph export $figure/F3_Non_Polluting_resid1_tfpop_s.png, replace
graph combine $figure/F3_Polluting_resid1_tfpop_s.gph $figure/F3_Non_Polluting_resid1_tfpop_s.gph, xsize(6) ysize(8) ycommon xcommon col(1) scheme(plotplainblind)
graph save $figure/F3_TFP, replace
graph export $figure/F3_TFP.png, replace
************************** Tabble 1. Baseline Results*****************************
use "tfp_small_QJE_final.dta",clear
* Authomatic bandwidth models:
local kernelfn "tri epa uni" // 核密度选择,对应triangular密度估计、epanechnikov密度估计、rdrobust进行的非参数估计
cap erase $result/T2_localRD.txt
cap erase $result/T2_localRD.xml
// tfpop_s是 No control
// resid1_tfpop_s 是 Station FE + industry FE absorbed 的TFP
// resid2_tfpop_s 是 Station by industry FE absorbed 的TFP
// distance_new 是 距离,负数为上游距离,正数为下游距离
// neg_ind0 ==1 是污染行业
foreach y of var tfpop_s resid1_tfpop_s resid2_tfpop_s{
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==1, kernel(`kvar') all vce(cluster site_id)
outreg2 using $result/T2_localRD, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
}
local kernelfn "tri epa uni"
foreach y of var tfpop_s resid1_tfpop_s resid2_tfpop_s {
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==0, kernel(`kvar') all vce(cluster site_id)
outreg2 using $result/T2_localRD, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_np) dec(2) append
}
}
**Insert Table
xmluse $result/T2_localRD.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("T2_localRD", replace)
************************** Figure 5 .Estimates by Year*****************************
use "graph_by_year",clear
replace b_lower = b-1.83*std_err // 90的置信区间
replace b_upper = b+1.83*std_err
keep if group ==1 // 保留污染行业
twoway (rspike b_upper b_lower year, lp(dash) lc(red)) ///
(scatter b year, sort mc(red)) ///
(line zero year , sort) , ylabel(-0.8(.4)1.2, labsize(*1)) xlabel(2000(1)2007) ///
xline(2002.5, lp(dash_dot)) xline(2005.5, lp(dash)) ///
text(1.15 2001 "Scientific Outlook of Development", place(se) box just(left) margin(l+2 t+1 b+1) width(53) bcolor(bluishgray)) ///
text(-0.45 2004.5 "11th 5-Year Plan", place(se) box just(left) margin(l+2 t+1 b+1) width(28) bcolor(bluishgray)) ///
ytitle("Estimated TFP Effect" " ") title("") yline(0) xtitle("Year") ///
legend(order(2 "Estimated Coefficient" 1 "90% CI") pos(6) size(small) symx(medium)) scheme(plotplainblind)
graph save $figure/F5_by_year, replace
graph export $figure/F5_by_year.png, replace
************************** Table 2. Within Firm RD *****************************
use "T2_MDRD.dta", clear
*****Install MDRD package
net describe mdrd, from(https://sites.google.com/site/r4ribas/codes/packages)
net install mdrd, force from(https://sites.google.com/site/r4ribas/codes/packages)
****Polluting industries
cap erase $result/DID_tfp_p.xml
cap erase $result/DID_tfp_p.txt
mdrd resid2_tfpop_s distance_new if neg_ind0==1, time(post03) all kernel(tri)
outreg2 using $result/DID_tfp_p, excel addtext(Kernel Type, `e(kernel)') ctitle(p_tfp) dec(2) append
mdrd resid2_tfpop_s distance_new if neg_ind0==1, time(post03) all kernel(epa)
outreg2 using $result/DID_tfp_p, excel addtext(Kernel Type, `e(kernel)') ctitle(p_tfp) dec(2) append
mdrd resid2_tfpop_s distance_new if neg_ind0==1, time(post03) all kernel(uni)
outreg2 using $result/DID_tfp_p, excel addtext(Kernel Type, `e(kernel)') ctitle(p_tfp) dec(2) append
****Non-Polluting industries
cap erase $result/DID_tfp_np.xml
cap erase $result/DID_tfp_np.txt
mdrd resid2_tfpop_s distance_new if neg_ind0==0, time(post03) all kernel(tri)
outreg2 using $result/DID_tfp_np, excel addtext(Kernel Type, `e(kernel)') ctitle(np_tfp) dec(2) append
mdrd resid2_tfpop_s distance_new if neg_ind0==0, time(post03) all kernel(epa)
outreg2 using $result/DID_tfp_np, excel addtext(Kernel Type, `e(kernel)') ctitle(np_tfp) dec(2) append
mdrd resid2_tfpop_s distance_new if neg_ind0==0, time(post03) all kernel(uni)
outreg2 using $result/DID_tfp_np, excel addtext(Kernel Type, `e(kernel)') ctitle(np_tfp) dec(2) append
************************** Table 3. THE UPSTREAM–DOWNSTREAM GAP IN INPUT AND OUTPUT LEVELS *****************************
*********** Post-2003 Results ***********
use "channels_QJE_final.dta", clear
*** Create Table ***
cap erase $result/TS_Channel.txt
cap erase $result/TS_Channel.xml
/*
Panel A: Output levels (downstream minus upstream)
RD in profit (10k RMB)
RD in value-added (log)
Panel B: Input levels (downstream minus upstream)
RD in # of employees (log)
RD in capital stock (log)
RD in intermediate input (log)
Panel C: Single factor productivity (downstream minus upstream)
RD in (VA/employee) (log)
RD in (VA/capital stock) (log)
*/
foreach y of var resid1_lrze resid1_lnv resid1_lnl resid1_lnk resid1_lnm resid1_lnv_l resid1_lnv_k{
rdrobust `y' distance_new if neg_ind0==1, kernel(tri) all vce(cluster site_id)
outreg2 using $result/TS_Channel, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
rdrobust `y' distance_new if neg_ind0==1, kernel(epa) all vce(cluster site_id)
outreg2 using $result/TS_Channel, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
rdrobust `y' distance_new if neg_ind0==1, kernel(uni) all vce(cluster site_id)
outreg2 using $result/TS_Channel, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
}
xmluse $result/TS_Channel.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("TS_Channel", replace)
*********** Pre-2003 Results ***********
use "$data/channels_Pre_QJE_final.dta",clear
cap erase $result/TS_Channel_Pre.txt
cap erase $result/TS_Channel_Pre.xml
foreach y of var resid1_lrze resid1_lnv resid1_lnl resid1_lnk resid1_lnm resid1_lnv_l resid1_lnv_k {
rdrobust `y' distance_new if neg_ind0==1, kernel(tri) all vce(cluster site_id)
outreg2 using $result/TS_Channel_Pre, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
rdrobust `y' distance_new if neg_ind0==1, kernel(epa) all vce(cluster site_id)
outreg2 using $result/TS_Channel_Pre, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
rdrobust `y' distance_new if neg_ind0==1, kernel(uni) all vce(cluster site_id)
outreg2 using $result/TS_Channel_Pre, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
}
xmluse $result/TS_Channel_Pre.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("TS_Channel_Pre", replace)
************************** Abatement in production process *****************************
use "abatement_QJE_final.dta",clear
cap erase $result/T_abatement.txt
cap erase $result/T_abatement.xml
** reduced production hours
rdrobust resid1_hours distance_new, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid prod hours) dec(0) replace
rdrobust resid1_hours distance_new, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid prod hours) dec(0) append
rdrobust resid1_hours distance_new, kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid prod hours) dec(0) append
** reduced water usage (changing towards less water-intensive technologies)
rdrobust resid1_log_water distance_new, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid log water input) dec(2) append
rdrobust resid1_log_water distance_new, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid log water input) dec(2) append
rdrobust resid1_log_water distance_new, kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid log water input) dec(2) append
********End-of-the-Pipe Technology********
**upstream firms own more abatement machines
rdrobust resid1_machine distance_new , kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid abate machine) dec(2) append
rdrobust resid1_machine distance_new , kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid abate machine) dec(2) append
rdrobust resid1_machine distance_new , kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid abate machine) dec(2) append
**upstream firms have higher abatement capacity
rdrobust resid1_total_capacity distance_new , kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid abate capacity) dec(0) append
rdrobust resid1_total_capacity distance_new , kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid abate capacity) dec(0) append
rdrobust resid1_total_capacity distance_new , kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_abatement, excel addtext(Kernel Type, `e(kernel)') ctitle(resid abate capacity) dec(0) append
****** Insert Table *****
xmluse $result/T_abatement.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("T_abatement", replace)
************************** THE UPSTREAM–DOWNSTREAM GAP IN EMISSIONS *****************************
use "water_emission_QJE_final.dta", clear
** Local Linear RD Results for Emission **
cap erase $result/T_localRD_emission.xml
cap erase $result/T_localRD_emission.txt
foreach y of var resid_log_cod resid_log_cod_intensity resid_log_nh resid_log_nh_intensity resid_log_waste_water resid_log_waste_water_intensity {
rdrobust `y' distance_new , kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_localRD_emission, excel addtext(Kernel Type, `e(kernel)') ctitle(`y') dec(2) append
rdrobust `y' distance_new , kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_localRD_emission, excel addtext(Kernel Type, `e(kernel)') ctitle(`y') dec(2) append
rdrobust `y' distance_new , kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_localRD_emission, excel addtext(Kernel Type, `e(kernel)') ctitle(`y') dec(2) append
}
***** Placebo Pollutants *****
use "air_emission_QJE_final.dta", clear
foreach y of var resid_log_so2 resid_log_nox {
rdrobust `y' distance_new , kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_localRD_emission, excel addtext(Kernel Type, `e(kernel)') ctitle(`y') dec(2) append
rdrobust `y' distance_new , kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_localRD_emission, excel addtext(Kernel Type, `e(kernel)') ctitle(`y') dec(2) append
rdrobust `y' distance_new , kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_localRD_emission, excel addtext(Kernel Type, `e(kernel)') ctitle(`y') dec(2) append
}
****** Insert Table *****
*** Insert all the Tables ***
xmluse $result/T_localRD_emission.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("T_localRD_emission", replace)
***************************** Emission Fee *****************************
cap erase $result/TS_Fee.txt
cap erase $result/TS_Fee.xml
* Authomatic bandwidth models:
foreach y of var resid1_l_pwf {
rdrobust `y' distance_new , bwselect(certwo) kernel(tri) all vce(cluster site_id)
outreg2 using $result/TS_Fee, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
rdrobust `y' distance_new , bwselect(certwo) kernel(epa) all vce(cluster site_id)
outreg2 using $result/TS_Fee, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
rdrobust `y' distance_new, bwselect(certwo) kernel(uni) all vce(cluster site_id)
outreg2 using $result/TS_Fee, excel addtext(Kernel Type, `e(kernel)') ctitle( `y') dec(2) append
}
xmluse $result/TS_Fee.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("TS_Fee", replace)
***************************** Table Political Incentive ***********************
use "PE_QJE_final.dta",clear
cap erase $result/T_political.txt
cap erase $result/T_political.xml
* in years when the prefecture party secretary has strong promotion incentives, effect size is larger
local kernelfn "tri epa uni"
* Authomatic bandwidth models:
foreach y of var resid1_tfpop_s {
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==1 & party_inc ==1, kernel(`kvar') all vce(cluster site_id)
outreg2 using $result/T_political, excel addtext(Kernel Type,(off) `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_high) dec(2) append
}
}
foreach y of var resid1_tfpop_s {
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==1 & party_inc ==0,kernel(`kvar') all vce(cluster site_id)
outreg2 using $result/T_political, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_low) dec(2) append
}
}
foreach y of var resid1_tfpop_s {
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==0 & party_inc ==1, kernel(`kvar') all vce(cluster site_id)
outreg2 using $result/T_political, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_high) dec(2) append
}
}
foreach y of var resid1_tfpop_s {
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==0 & party_inc ==0, kernel(`kvar') all vce(cluster site_id)
outreg2 using $result/T_political, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_low) dec(2) append
}
}
xmluse $result/T_political, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("T_political", replace)
***************************** Table Political Incentive *****************************
***** Auto vs. Manual Stations *****
use "auto_QJE_final.dta",clear
cap erase $result/T_auto.txt
cap erase $result/T_auto.xml
* Authomatic bandwidth models:
//污染行业
foreach y of var resid1_tfpop_s {
rdrobust `y' distance_new if neg_ind0==1 & automatic==1, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
rdrobust `y' distance_new if neg_ind0==1 & automatic==1, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
rdrobust `y' distance_new if neg_ind0==1 & automatic==1, kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
foreach y of var resid1_tfpop_s {
rdrobust `y' distance_new if neg_ind0==1 & automatic==0, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
rdrobust `y' distance_new if neg_ind0==1 & automatic==0, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
rdrobust `y' distance_new if neg_ind0==1 & automatic==0, kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
// 非污染行业
foreach y of var resid1_tfpop_s {
rdrobust `y' distance_new if neg_ind0==0 & automatic==1, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
rdrobust `y' distance_new if neg_ind0==0 & automatic==1, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
rdrobust `y' distance_new if neg_ind0==0 & automatic==1,bwselect(msecomb1) kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
foreach y of var resid1_tfpop_s {
rdrobust `y' distance_new if neg_ind0==0 & automatic==0, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
rdrobust `y' distance_new if neg_ind0==0 & automatic==0, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
rdrobust `y' distance_new if neg_ind0==0 & automatic==0, kernel(uni) all vce(cluster site_id)
outreg2 using $result/T_auto, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
xmluse $result/T_auto.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("T_auto", replace)
********** SOE vs. Private Firms **********
use "soe_vs_private_QJE_final", clear
cap erase $result/T_soe_vs_private.txt
cap erase $result/T_soe_vs_private.xml
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & soe == 0, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & soe == 0, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & soe == 0, kernel(uniform) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & soe == 0, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & soe == 0, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & soe == 0, kernel(uniform) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & soe == 1, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & soe == 1, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & soe == 1, kernel(uniform) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & soe == 1, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & soe == 1, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & soe == 1, kernel(uniform) all vce(cluster site_id)
outreg2 using $result/T_soe_vs_private, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
*** Insert all the Tables ***
xmluse $result/T_soe_vs_private.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("T_soe_vs_private", replace)
********** Big vs. Small Firms **********
use "big_vs_small_QJE_final", clear
cap erase $result/T_big_vs_small.txt
cap erase $result/T_big_vs_small.xml
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & firm_big == 0, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & firm_big == 0, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & firm_big == 0, kernel(uniform) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & firm_big == 0, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & firm_big == 0, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & firm_big == 0, kernel(uniform) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & firm_big == 1, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & firm_big == 1, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==1 & firm_big == 1, kernel(uniform) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_p) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & firm_big == 1, kernel(tri) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & firm_big == 1, kernel(epa) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
rdrobust resid1_tfpop_s distance_new if neg_ind0==0 & firm_big == 1, kernel(uniform) all vce(cluster site_id)
outreg2 using $result/T_big_vs_small, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(pe_tfpop_np) dec(2) append
xmluse $result/T_big_vs_small.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("T_big_vs_small", replace)
********** River Basin: South-North Water Diversion Project **********
use "NSBD_QJE_final", clear
cap erase $result/T_localRD_basin.txt
cap erase $result/T_localRD_basin.xml
* Authomatic bandwidth models:
local kernelfn "epa tri uni"
foreach y of var resid1_tfpop_s{
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==1 & nsbd==0, kernel(`kvar') vce(cluster site_id)
outreg2 using $result/T_localRD_basin, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
}
foreach y of var resid1_tfpop_s{
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==0 & nsbd==0, kernel(`kvar') vce(cluster site_id)
outreg2 using $result/T_localRD_basin, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
}
foreach y of var resid1_tfpop_s{
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==1 & nsbd==1, kernel(`kvar') vce(cluster site_id)
outreg2 using $result/T_localRD_basin, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
}
foreach y of var resid1_tfpop_s{
foreach kvar of local kernelfn {
rdrobust `y' distance_new if neg_ind0==0 & nsbd==1, kernel(`kvar') vce(cluster site_id)
outreg2 using $result/T_localRD_basin, excel addtext(Kernel Type, `e(kernel)') addstat(bandwidth, e(h_l)) ctitle(`y'_p) dec(2) append
}
}
xmluse $result/T_localRD_basin.xml, doctype(excel) sheet(Sheet1) cells(A2:FZ100) allstring missing nocompress clear
export excel using $result/Tables_TFP.xlsx, sheet("T_localRD_basin", replace)