2024年CIMERS暑期班,因果推断最新进展+量化宏观,全新回归!
👉面板数据模型(DID等)最新进展及其stata应用,点击查看
👉DSGE第一课与Dynare编程,点击查看
成为CIMERS内部学员,你可以获得
⭐ 高质量课程,详细课件,可复用代码及数据
⭐ 许老师详尽答疑服务,知无不言,学无止境
⭐ 高质量的交流社群(主要为硕博以及高校教师)
⭐ 许老师增值讲座,文献解读,模型讲解
⭐ 未来课程内部学员折扣
⭐⭐诚邀您加入CIMERS,许老师正在寻找好的合作者,一起作出高质量研究⭐⭐
报名任意课程即可成为CIMERS内部学员
恳请各位老师同学动动发顶刊的小手,点个赞和在看,让更多人看到我们的研究,您的支持是CIMERS最大的动力!
从今天开始,我们搬运Scott Cunningham的“Pedro’s diff in diff checklist”【有兴趣的人可以点击这里关注他的blog】。
大家也许还记得,Sant' Anna有一个十步DID:
第四步:处理配置机制---阿什费尔特沉降(Ashenfelter's Dip)
第四步:什么样的处理配置机制会打破平行趋势假设
前面,我们看过了三种处理配置机制——基于处理前未处理潜在结果、基于处理前未处理潜在结果的变化、基于可观测协变量。这些处理配置机制都不会打破(条件)平行趋势假设,只要我们选择恰当的回归声明。
今天,给大家呈现一种会打破平行趋势假设的处理配置机制。即个体以“最优”方式选择接受处理,平行趋势就会失效,这意味着只有那些处理效应为正的人才会选择进入处理,而那些处理效应为0或者负的人会拒绝处理。Cunningham(2024)称之为“完美医生”,也有人称其为“根据处理效应来选择”,或者“Roy模型”。
完美医生的选择
想象一下,有一千名社会科学家渴望学习最新的统计软件语言 Rattlesnake。他们都知道 R、Stata、python 和 julia,但由于工作者的年龄、在其他语言方面的人力资本、他们的合作者网络、他们的工作和他们自己的天赋存在一些差异,并不是每个人都能从学习 Rattlesnake 中获益,因为学习它需要付出很多努力。不过,有些人会有所收获,而且收获颇丰。但有些人不会。事实上,有些人学习它会获得负面回报,因为这是一种很难的语言,需要从已熟练的编程语言中抽时间和精力来学习,而且他们在其他方面有比较优势。
想象一下,每个工人都可以咨询一位名叫安德鲁斯博士的计量经济学医生。这位医生在工作中堪称完美。她不仅是一位出色的计量经济学家,还能告诉社会科学家学习Rattlesnake 的确切回报。她只需检查社会科学家的一缕头发,就能推断出学习Rattlesnake 的确切回报。
乔纳森,完美医生和正的处理效应
有一天,乔纳森来到计量经济学诊所进行检查,并进行了如下交流。
乔纳森:安德鲁斯博士,我正在考虑学习Rattlesnake 。我听说它可以加快我的工作速度。
安德鲁斯博士:乔纳森,见到你真是太好了。我很乐意帮你解答这个问题。请给我一缕你的头发。
乔纳森:谢谢安德鲁斯博士。给你。<他递给她一缕用金丝带包着的头发>
安德鲁斯博士:<盯着头发看了一会儿,用手指把它翻来覆去几次,然后抬起头> 。看来学习Rattlesnake 语言对你的平均效应是,在未来两年内,更好的发表,外部报价和加薪将为你带来 7,500 美元的额外薪酬。我建议你去学习。
乔纳森也这么做了。第二天,他就报名参加了Rattlesnake 课程。
完美医生,斯科特和负的处理效应
有一天,斯科特来到计量经济学诊所,抱怨背痛、失眠以及照顾太多野猫带来的压力。
斯科特:医生,猫咪们就是不和睦相处。我快疯了,因为照顾它们占用了我所有的时间。其中一只还拒绝使用猫砂机器人。它们对我很好,而且很需要照顾,但我希望它们能更友好地对待彼此。如果它们也能使用真正的猫砂,成为真正的室内猫,而不是这些不知道如何正确使用厕所的可笑动物,那就太好了。
安德鲁斯医生:斯科特,听起来你在家里过得有点辛苦。但我真的不是那种医生。我更擅长计量经济学,而不是为人们提供如何管理私人生活和宠物纠纷的咨询。
斯科特:嗯,就是这样。有门新课可以教我 Rattlesnake,这是每个人都在谈论的新型统计软件语言。我认为它真的能帮助我,因为我的朋友乔纳森说你告诉他,由于速度快了很多,他的论文质量也提高了。他告诉我他甚至每年加薪 7,500 美元!所以我肯定想要这个。
安德鲁斯博士:没错,斯科特。乔纳森两年的平均处理效应确实为 7,500 美元。我一眼就能看出来。但请记住,每个人学习 Rattlesnake的效果都不一样。乔纳森的效果是积极的,并不意味着你的效果也是积极的。你为什么不把你的头发给我,我来检查一下呢。
斯科特:<因为这是一个故事,所以斯科特不是秃头(还记得,我读博士的时候,大家最关心的就是什么洗发水对防脱发有奇效O(∩_∩)O哈哈~),而是有一头乌黑的头发,就像月光下的湖水。他把头发剪下来递给她。>给你。
安德鲁斯博士:是的,正如我所想。如果你上这门课,你的收入将减少11,500 美元。
斯科特:What弄啥呢?为什么?!
安德鲁斯博士:我不知道。我只知道每个人的个体处理效应,因为我在这方面很擅长,但如果我不得不猜测的话,那是因为你养了那么多猫,它们给你带来了压力和失眠。我怀疑你是否能因为所有的担忧而集中注意力。如果是我,我会忽视Rattlesnake。继续利用你已有的人力资本尽可能地提高生产力。也许明年当你生活中的一些协变量发生变化时,这些处理效应会有所不同,但目前还不一样。
<说完,斯科特离开了,并决定不再参加工作中的 Rattlesnake计划>
基于处理收益的选择
在因果推断方面,对处理收益的选择是悲剧性的。当以最佳方式完成时,如果不对问题施加一些非常极端的结构限制,可能真的没有办法识别因果效应。我将向你展示“完美医生分类”对我们的处理组类别的影响:处理组只有正收益,对照组只有零或负收益。
绿色柱状组由像 Jonathan 这样的人组成,他们被最佳地分类到Rattlesnake学习中,而白色组由像 Scott 这样的人组成,他们的处理效应是负面的,因此他们没有参加编程语言的学习。在我进行的数据生成过程中,我得到了以下结果:
1、条件平行趋势(基于年龄和 GPA)
* Generate fixed effect with control group making 10,000 more at baseline
qui gen unit_fe = 40000 + rnormal(0,5000)
* Generate Potential Outcomes Based on Age and GPA trends plus constant trend
gen e = rnormal(0, 1500)
qui gen y0 = unit_fe + 100 * age + 1000 * gpa + e if year == 1987
qui replace y0 = unit_fe + 1000 + 150 * age + 1500 * gpa + e if year == 1988
qui replace y0 = unit_fe + 2000 + 200 * age + 2000 * gpa + e if year == 1989
qui replace y0 = unit_fe + 3000 + 250 * age + 2500 * gpa + e if year == 1990
qui replace y0 = unit_fe + 4000 + 300 * age + 3000 * gpa + e if year == 1991
qui replace y0 = unit_fe + 5000 + 350 * age + 3500 * gpa + e if year == 1992
2、年龄和 GPA 方面的处理效应不同,但没有动态变化
* Covariate-based treatment effect heterogeneity
gen y1 = y0
replace y1 = y0 + 1000 + 250 * age + 1000 * gpa if year >= 1991
* Treatment effect
gen delta = y1 - y0
label var delta "Treatment effect for unit i"
3、完美医生选择处理
* Calculate average treatment effect for each unit in post-period
bysort id (year): egen avg_delta_post = mean(delta) if year >= 1991
bysort id: egen avg_delta = mean(avg_delta_post)
* Assign treatment based on positive average treatment effect
gen treat = (avg_delta > 0)
* Generate treatment dates
gen treat_date = 0
replace treat_date = 1991 if treat == 1
当我创建这种内生处理组时,我实际上违反了平行趋势。你可以在我的控制组均值 Y(0)(这将是一个观察到的均值,因为我们总是观察到控制组的 Y(0))和处理组均值 Y(0)(这将是反事实的,因为我们只观察到治疗后的治疗组的 Y(1))的图中看到这一点。
“完美医生”配置机制和“阿申菲尔特下降”配置机制的比较
如果你还记得的话,这种选择机制与我们前几天做的 Ashenfelter Dip 配置机制有着惊人的不同。
在A' dip例子中,即使基于处理前收入下降进行排序也不一定违反平行趋势。下面是 Ashenfelter Dip。请注意,在该例子中,选择处理不是基于项目的未来回报,而是基于处理前 Y(0)的下降。理解它们之间的差异很重要。完美医生根据未来的将个体分配给处理。Ashenfelter's Dip 根据分配给处理。这些对于你是否要选择DID研究设计具有重大影响,因为完美医生会破坏DID设计,但Ashenfelter's Dip 可能不会。这里有两张图片可以帮助我们可视化这个差异。上图仅显示潜在结果,而下图则显示处理组和对照组的实际收益以及处理组的处理后反事实 Y(0) 。如你所见,Ashenfelter's Dip 不一定违反平行趋势(即使它会产生非零的处理前趋势)。
在“完美医生”配置机制下,事件研究结果
我们可以从前面的例子中看到,完美医生根据完美预见对处理进行分类将破坏你的平行趋势假设,即使控制用于生成潜在结果本身的协变量也无法解决这个问题。让我们看看。控制年龄和 GPA 的 OLS 和双重稳健估计量(Sant'Anna 和 Zhou 2020)。
这是从运行了 1,000 次蒙特卡洛模拟中得出的。我使用双重稳健的 CSDID 来处理基期协变量,并将处理后虚拟变量与年龄和 GPA 进行交互,这样它们就不会被删除。由于年龄和 GPA 都是预先确定的,因此交互项仅能让我们将它们作为控制项包括在内,而不会在差分中删除它们,因为它们是时间不变的。
红色 X 表示“真实处理效应”。它衡量了 1991 年和 1992 年学习新编程语言工人的平均处理效应。由于效应随时间保持不变,因此两个 X 相同 - 它们等于 2,462 美元。
但请注意 OLS的结果——两年的处理效应均为负值。具体来说,1991 年的系数为 -2,429 美元,1992 年的系数为 -1,583 美元。
在你开始对双重稳健性(使用 CSDID 或此处的 CS 进行估计)感到兴奋之前,请暂停一下。它实际上并没有变得更好。1,000 次模拟的平均点估计在 1991 年为 23 美元,在 1992 年为 168 美元。至少效应为正,但这只是平均水平。1,000 次模拟的估计范围非常大。对于 1991 年,它们的范围从 -20,972 美元到 +27,466 美元,即统计不显著。
结论
为什么它们的表现都这么差?原因很简单。因为条件平行趋势和平行趋势都不成立。问题不在于处理效应的异质性。问题在于处理配置机制。当每个个体完全预见处理收益后,选择进行处理时,DID就不是一个好的研究设计了,因为这种“完美医生”的分类模式会破坏平行趋势。
我认为Pedro在第四步中谈到了这一点。内容如下:
步骤 4:谨慎选择对照组和平行趋势假设:谁决定处理?他们知道什么?允许哪种选择?
有趣的是,我认为Pedro告诉你要仔细选择对照组和平行趋势假设,然后用冒号告诉你这涉及的内容。请注意,他并没有说“寻找具有可比处理前趋势的个体”。相反,他说我们所有人都应该尽可能地弄清楚为什么选择某些个体而不是其他个体。这是基于对处理效应的了解吗?这些知识有多完美?如果它是完美医生级别的知识,这是我们在向学生教授效用最大化时所追求的,或者更基本的是,“当且仅当边际效益大于边际成本时才选择一种行动”。如果一个人能做到这一点,那么他们就是自己的完美医生。如果算法可以做到这一点,因为它可以完美地估计个体处理效应,那么它也可能产生重大的内生性问题,而DID无法解决这些问题,因为DID如果没有平行趋势就永远无法识别真实处理效应。
不过,暂时先不管是否有解决办法。我的建议是停下来,试着更好地理解导致人们接受这种处理的过程背后的动机,因为正如我们在这个和我们之前处理配置机制,有很多选择过程实际上保持了平行趋势的完整性。只是,杀死它的是经济学家倾向于近乎信仰的东西——理性经济人。如果经济人是代表他人为自己选择处理的人,那么简单的比较都是有偏的,而且简单的平均一阶差分比较也是有偏的。这就是教训——在你继续之前,花很多时间试图弄清楚个体接受处理的过程。这一点非常非常非常重要。
完整stata代码:
* step4_roy.do. Selection on treatment gains or "Perfect Doctor" (e.g., Roy)
clear all
capture log close
set seed 54321
********************************************************************************
* Define dgp
********************************************************************************
cap program drop dgp
program define dgp
* First create the states
quietly set obs 40
gen state = _n
* Generate 1000 workers. These are in each state. So 25 per state.
quietly expand 25
bysort state: gen worker=runiform(0,5)
label variable worker "Unique worker fixed effect per state"
quietly egen id = group(state worker)
* Generate Covariates (Baseline values)
gen age = rnormal(35, 10)
gen gpa = rnormal(2.0, 0.5)
* Center Covariates (Baseline)
sum age, meanonly
qui replace age = age - r(mean)
sum gpa, meanonly
qui replace gpa = gpa - r(mean)
* Generate the years
quietly expand 6
sort state
bysort state worker: gen year = _n
* years 1987 -- 1992
replace year = 1986 + year
* Post-treatment
gen post = 0
qui replace post = 1 if year >= 1991
* Generate fixed effect with control group making 10,000 more at baseline
qui gen unit_fe = 40000 + rnormal(0,5000)
* Generate Potential Outcomes Based on Age and GPA trends plus constant trend
gen e = rnormal(0, 1500)
qui gen y0 = unit_fe + 100 * age + 1000 * gpa + e if year == 1987
qui replace y0 = unit_fe + 1000 + 150 * age + 1500 * gpa + e if year == 1988
qui replace y0 = unit_fe + 2000 + 200 * age + 2000 * gpa + e if year == 1989
qui replace y0 = unit_fe + 3000 + 250 * age + 2500 * gpa + e if year == 1990
qui replace y0 = unit_fe + 4000 + 300 * age + 3000 * gpa + e if year == 1991
qui replace y0 = unit_fe + 5000 + 350 * age + 3500 * gpa + e if year == 1992
* Covariate-based treatment effect heterogeneity
gen y1 = y0
replace y1 = y0 + 1000 + 250 * age + 1000 * gpa if year >= 1991
* Treatment effect
gen delta = y1 - y0
label var delta "Treatment effect for unit i"
* Calculate average treatment effect for each unit in post-period
bysort id (year): egen avg_delta_post = mean(delta) if year >= 1991
bysort id: egen avg_delta = mean(avg_delta_post)
* Assign treatment based on positive average treatment effect
gen treat = (avg_delta > 0)
* Generate treatment dates
gen treat_date = 0
replace treat_date = 1991 if treat == 1
* Generate observed outcome based on treatment assignment
gen earnings = y0
qui replace earnings = y1 if treat == 1 & year >= 1991
end
********************************************************************************
* Draw a sample
********************************************************************************
clear
quietly dgp
* Check models work
reg earnings treat##ib1990.year post##c.age post##c.gpa , robust
csdid earnings age gpa , ivar(id) time(year) gvar(treat_date)
csdid_plot, group(1991)
collapse (mean) y0, by(year treat)
tsset treat year
twoway (tsline y0 if treat==0) (tsline y0 if treat==1), xline(1990.5) ytitle("Mean Y(0)") ttitle("Year") title("Evolution of untreated potential outcome") subtitle("Perfect Doctor Assignment") legend(order(1 "Control" 2 "Treated"))
graph export "step4_y0_roy.png", as(png) name("Graph") replace
********************************************************************************
* Monte-carlo simulation
********************************************************************************
cap program drop simulation
program define simulation, rclass
clear
quietly dgp
// True ATT
gen true_att = y1 - y0
qui sum true_att if treat == 1 & year == 1991
return scalar att_1991 = r(mean)
qui sum true_att if treat == 1 & year == 1992
return scalar att_1992 = r(mean)
// CSDID
qui csdid earnings age gpa , ivar(id) time(year) gvar(treat_date)
matrix b = e(b)
return scalar cs_pre1987 = b[1,1]
return scalar cs_pre1988 = b[1,2]
return scalar cs_pre1989 = b[1,3]
return scalar cs_post1991 = b[1,4]
return scalar cs_post1992 = b[1,5]
// OLS
qui reg earnings treat##ib1990.year post##c.age post##c.gpa , robust
return scalar ols_pre1987 = _b[1.treat#1987.year]
return scalar ols_pre1988 = _b[1.treat#1988.year]
return scalar ols_pre1989 = _b[1.treat#1989.year]
return scalar ols_post1991 = _b[1.treat#1991.year]
return scalar ols_post1992 = _b[1.treat#1992.year]
end
simulate att_1991 = r(att_1991) ///
att_1992 = r(att_1992) ///
cs_pre1987 = r(cs_pre1987) ///
cs_pre1988 = r(cs_pre1988) ///
cs_pre1989 = r(cs_pre1989) ///
cs_post1991 = r(cs_post1991) ///
cs_post1992 = r(cs_post1992) ///
ols_pre1987 = r(ols_pre1987) ///
ols_pre1988 = r(ols_pre1988) ///
ols_pre1989 = r(ols_pre1989) ///
ols_post1991 = r(ols_post1991) ///
ols_post1992 = r(ols_post1992), ///
reps(1000) seed(54321): simulation
// Summarize results
sum
// Store results
save ./step4_roy.dta, replace
********************************************************************************
* Plot results
********************************************************************************
use ./step4_roy.dta, clear
* Calculate means and standard deviations for OLS variables
summarize ols_pre1987
local ols_pre1987_mean = r(mean)
local ols_pre1987_sd = r(sd)
summarize ols_pre1988
local ols_pre1988_mean = r(mean)
local ols_pre1988_sd = r(sd)
summarize ols_pre1989
local ols_pre1989_mean = r(mean)
local ols_pre1989_sd = r(sd)
summarize ols_post1991
local ols_post1991_mean = r(mean)
local ols_post1991_sd = r(sd)
summarize ols_post1992
local ols_post1992_mean = r(mean)
local ols_post1992_sd = r(sd)
* Calculate means and standard deviations for CSDID variables
summarize cs_pre1987
local cs_pre1987_mean = r(mean)
local cs_pre1987_sd = r(sd)
summarize cs_pre1988
local cs_pre1988_mean = r(mean)
local cs_pre1988_sd = r(sd)
summarize cs_pre1989
local cs_pre1989_mean = r(mean)
local cs_pre1989_sd = r(sd)
summarize cs_post1991
local cs_post1991_mean = r(mean)
local cs_post1991_sd = r(sd)
summarize cs_post1992
local cs_post1992_mean = r(mean)
local cs_post1992_sd = r(sd)
summarize att_1992
local true_att_1991 = r(mean)
summarize att_1991
local true_att_1992 = r(mean)
* Create a new dataset for plotting
clear
set obs 6
* Define the years
gen year = 1987 + _n - 1
* True ATT values
gen truth = 0
replace truth = `true_att_1991' if year == 1991
replace truth = `true_att_1992' if year == 1992
* OLS means and confidence intervals
gen ols_mean = .
gen ols_ci_lower = .
gen ols_ci_upper = .
replace ols_mean = `ols_pre1987_mean' if year == 1987
replace ols_mean = `ols_pre1988_mean' if year == 1988
replace ols_mean = `ols_pre1989_mean' if year == 1989
replace ols_mean = 0 if year == 1990
replace ols_mean = `ols_post1991_mean' if year == 1991
replace ols_mean = `ols_post1992_mean' if year == 1992
replace ols_ci_lower = ols_mean - 1.96 * `ols_pre1987_sd' if year == 1987
replace ols_ci_lower = ols_mean - 1.96 * `ols_pre1988_sd' if year == 1988
replace ols_ci_lower = ols_mean - 1.96 * `ols_pre1989_sd' if year == 1989
replace ols_ci_lower = 0 if year == 1990
replace ols_ci_lower = ols_mean - 1.96 * `ols_post1991_sd' if year == 1991
replace ols_ci_lower = ols_mean - 1.96 * `ols_post1992_sd' if year == 1992
replace ols_ci_upper = ols_mean + 1.96 * `ols_pre1987_sd' if year == 1987
replace ols_ci_upper = ols_mean + 1.96 * `ols_pre1988_sd' if year == 1988
replace ols_ci_upper = ols_mean + 1.96 * `ols_pre1989_sd' if year == 1989
replace ols_ci_upper = 0 if year == 1990
replace ols_ci_upper = ols_mean + 1.96 * `ols_post1991_sd' if year == 1991
replace ols_ci_upper = ols_mean + 1.96 * `ols_post1992_sd' if year == 1992
* CSDID means and confidence intervals
gen csdid_mean = .
gen csdid_ci_lower = .
gen csdid_ci_upper = .
replace csdid_mean = `cs_pre1987_mean' if year == 1987
replace csdid_mean = `cs_pre1988_mean' if year == 1988
replace csdid_mean = `cs_pre1989_mean' if year == 1989
replace csdid_mean = 0 if year == 1990
replace csdid_mean = `cs_post1991_mean' if year == 1991
replace csdid_mean = `cs_post1992_mean' if year == 1992
replace csdid_ci_lower = csdid_mean - 1.96 * `cs_pre1987_sd' if year == 1987
replace csdid_ci_lower = csdid_mean - 1.96 * `cs_pre1988_sd' if year == 1988
replace csdid_ci_lower = csdid_mean - 1.96 * `cs_pre1989_sd' if year == 1989
replace csdid_ci_lower = 0 if year == 1990
replace csdid_ci_lower = csdid_mean - 1.96 * `cs_post1991_sd' if year == 1991
replace csdid_ci_lower = csdid_mean - 1.96 * `cs_post1992_sd' if year == 1992
replace csdid_ci_upper = csdid_mean + 1.96 * `cs_pre1987_sd' if year == 1987
replace csdid_ci_upper = csdid_mean + 1.96 * `cs_pre1988_sd' if year == 1988
replace csdid_ci_upper = csdid_mean + 1.96 * `cs_pre1989_sd' if year == 1989
replace csdid_ci_upper = 0 if year == 1990
replace csdid_ci_upper = csdid_mean + 1.96 * `cs_post1991_sd' if year == 1991
replace csdid_ci_upper = csdid_mean + 1.96 * `cs_post1992_sd' if year == 1992
* Shift years slightly to avoid overlap
gen year_ols = year - 0.1
gen year_csdid = year
* Plotting
twoway (scatter truth year, mcolor(maroon) msize(6-pt) msymbol(lgx) mlabcolor() mfcolor(cranberry) mlwidth(medthick)) ///
(scatter ols_mean year_ols, mcolor(navy) msize(6-pt)) ///
(line ols_mean year_ols, lcolor(blue) lwidth(medthick)) ///
(rcap ols_ci_lower ols_ci_upper year_ols, lcolor(blue)) ///
(scatter csdid_mean year_csdid, mcolor(saddle) msize(6-pt)) ///
(line csdid_mean year_csdid, lcolor(brown) lwidth(medthick) lpattern(dash)) ///
(rcap csdid_ci_lower csdid_ci_upper year_csdid, lcolor(brown) lpattern(dash)), ///
title("Event Study: OLS, CSDID, and Truth") ///
subtitle("Perfect Doctor Treatment Assignment") ///
note("DGP uses conditional parallel trends. OLS includes additive controls; CS uses double robust." "No differential timing. 1000 Monte Carlo simulations.") ///
legend(order(1 "Truth" 3 "OLS" 6 "CS") ///
label(1 "Truth" ) ///
label(2 "OLS" ) ///
label(3 "CS" )) ///
xline(1990.5, lpattern(dash) lcolor(gray))
* Export the graph
graph export "/Users/scunning/Library/CloudStorage/Dropbox-MixtapeConsulting/scott cunningham/0.1 Mixtape Consulting/Substack/Code/step4_roy_combined.png", as(png) name("Graph") replace
clear
quietly dgp
* Visualize the treatment effects
twoway (histogram delta if treat==1 & post==1, color(green)) ///
(histogram delta if treat==0 & post==1, fcolor(none) lcolor(black)), ///
title("Distribution of treatment effects") ///
subtitle("Perfect Doctor Assignment") ///
legend(order(1 "Treated" 2 "Not treated"))
graph export "/Users/scunning/Library/CloudStorage/Dropbox-MixtapeConsulting/scott cunningham/0.1 Mixtape Consulting/Substack/Code/step4_roy_te.png", as(png) name("Graph") replace
capture log close
exit
注:(1)相关讲稿、Slides和stata do文件在许文立老师的github及其主页上公布。
(2)CIMERS学员/付费会员注意后续线上讲座通知。
(3)更多计量和stata内容,请参见经验分析方法及Stata命令汇总
72、【应用计量系列72】断点回归(2):丝滑世界里找“跳跃”
73、【应用计量系列73】交叠DID估计量 :stata包csdid升级版
74、【应用计量系列74】控制组群固定效应还是个体固定效应?
75、【应用计量系列75】合成控制法的新推断框架和stata应用
76、【应用计量系列76】平行趋势的秘密(一):平行趋势假设的类型
77、【应用计量系列77】平行趋势的秘密(二):明知不可为而为之
79、【应用计量系列79】平行趋势的秘密(三):如何给平行趋势假设提供经验证据?
81、【应用计量系列81】平行趋势的秘密(四):如何给平行趋势假设提供经验证据?
82、【应用计量系列82】因果推断中的纠偏机器学习方法(DDML)
85、【应用计量系列85】DID最新文献:共同相关效应DID(CCE-DID)
86、【应用计量系列86】新DID的Stata包升级版csdid2
92、【应用计量系列92】事件研究对平行趋势假设检验的效力及stata操作
94、【应用计量系列94】因果效应推断概述课后作业:随机实验分析
95、【应用计量系列95】匹配估计量(1):小小的匹配从来没有伤害过任何人
97、【应用计量系列97】匹配估计量(2):条件独立性假设、敏感性检验及stata操作
99、【应用计量系统99】匹配估计量(3):精确匹配与共同支持假设
100、【应用计量系列100】最新的交错处理效应估计量:随机交错处理下,更有效率的估计量及其stata操作
101、【应用计量系列101】Stata 18新功能(1):异质性处理效应
102、【应用计量系列102】stata 18新功能(2):培根分解
103、【应用计量系列103】一文读懂线性回归的标准误与stata应用
【应用计量系列100】随机交错处理下,更有效率的估计量及其stata操作(Update)
105、【应用计量系列105】DID Handbook(持续更新)
106、【应用计量系列106】标准误太大,系数不显著?也许弄错了标准误的来源
107、【应用计量系列107】动态合成双重差分及stata操作
108、【应用计量系列108】异质性处理效应稳健估计量:dCDH估计量
118、【应用计量系列118】《双重差分法的最新理论进展与经验研究新趋势》附录B
119、【应用计量系列119】DID的平行趋势,真的理解,并会用了吗?兼论平行趋势敏感性检验及其stata应用
121、【应用计量系列121】工具变量的强弱检验与stata应用
122、【应用计量系列122】最新异质性处理效应估计量:局部投影法DID的stata命令与例子
123、【应用计量系列123】进入退出DID的稳健估计量和stata例子
124、【应用计量系列124】DID:面板数据与重复截面数据
126、【应用计量系列126】新DID的事件研究图,理解对了吗?
127、【应用计量系列 127】新 DID 的事件研究图,理解对了呀?(续)
128、【应用计量系列 128】一图知因果:因果推断方法选择流程图
129、【应用计量系列129】堆叠DID(stacked DID)及其应用
131、【应用计量系列131】不平行的DD,平行的DDD与stata应用
132、【应用计量经济系列 132】stata 中固定效应模型的命令注意事项
133、【应用计量系列 133】不要这么用异质性处理效应稳健估计量
135、【应用计量系列 135】DID 的平行趋势支持证据的安慰剂检验
137、【应用计量系列137】连续DID的异质性处理效应与stata操作(升级版)
138、【应用计量系列138】推荐多看看Jeff老爷子的东西
140、【应用计量系列 140】Sant' Anna: DID Check List
141、【应用计量系列141】DID的稳健性检验:不可观测的混淆因子-SIV(理论篇)
142、【应用计量系列142】Bartik IV/SSIV到底要怎么应用?
145、【应用计量系列145】Sant' Anna的DID规定动作(1):处理模式图
146、【应用计量系列146】Sant' Anna的DID规定动作(2):每类处理中处理个体数
147、【应用计量系列147】Sant' Anna的DID规定动作(3):画出每个处理类别的平均结果时序图
148、【应用计量系列148】Sant' Anna的DID规定动作(4-1):写好制度背景---处理配置机制
149、【应用计量系列149】Sant' Anna的DID规定动作(4-2):处理配置机制~一场星际会议的讨论
150、【应用计量系列150】Sant' Anna的DID规定动作(4-3):处理配置机制—Ashenfelter's Dip
151、【应用计量系列151】Sant' Anna的DID规定动作(4-4):处理配置机制——基于可观测协变量的处理
点击蓝色链接,即可查看详细课程大纲
CIMERS在线课程列表
因果推断系列视频课程主要内容包括:
(1)DID、交叠DID及其stata案例;
(2)事件研究及其stata案例;
(3)合成控制法及其stata案例;
(4)平行趋势检验及其stata案例
(5)断点回归及其stata案例
DSGE基准模型与Dynare编程入门
(1)实际经济周期模型(RBC)
(2)新凯恩斯主义模型(NK)
(3)金融中介
(4)环境DSGE模型
(5)劳动市场搜寻与匹配模型
(6)开放经济DSGE模型
异质性代理人模型与应用
(1)投资资产定价模型
(2)数值算法
(3)宏观金融前沿课题
绿色金融DSGE
(1)金融摩擦的DSGE模型:抵押约束、BGG、金融机构
(2)环境DSGE
(3)绿色金融DSGE
成为CIMERS内部学员,你可以获得
⭐高质量视频课程,详细课件资料,可复用代码及数据
⭐许老师详尽的答疑服务,知无不言,学无止境
⭐高质量的交流社群(主要为硕博以及高校教师)
⭐许老师增值讲座,包括但不限于文献解读,模型讲解
⭐⭐诚邀您加入CIMERS,许老师正在寻找好的合作者,一起作出高质量研究⭐⭐
咨询购买请联系
联系人:吴峰宇老师
联系电话:184 7751 1575
联系邮箱:cimers_dsge@econmod.cn
其它事项:可开具培训、技术服务、咨询等类型的增值税普票
更多课程信息,扫描下方二维码咨询:
特别提醒:非诚勿扰!