网易首页 > 网易号 > 正文 申请入驻

RDD断点回归设计的步骤和R代码指南

0
分享至

欢迎投稿(荐稿)计量经济圈,计量相关都行

箱:econometrics666@sina.cn

编辑整理: @计量经济圈(ID: econometrics666); 来源: 熊彼特的厨房 公众号

RDD断点回归设计越来越来越流行,在因果识别中的地位很高,因为是在一个断点处的两端进行比较,那么这个treatment效应能够较好的识别,下面这篇文章将会领着计量经济圈的圈友去认识RDD并且知道操作的步骤和Stata代码。想要进一步了解RDD这种方法以及其他因果推断技巧的,进入计量经济圈社群交流(文后)

目前常见的用于RDD计算的R包分别有rdd, rdrobust, rddtools。Thoemmes等 (2017)的论文比较了这三个包的异同。

Thoemmes(2017)从实践的角度,进一步将RD的步骤分为三类:Assumption Checks,Estimation, Sensitivity Checks。我认为这里的简要归纳要比Lee和Lemieux(2010)更清楚简洁。

Assumption Checks实际上对应了RD的三个前提假设,分别是配置变量存在断点,对应着McCrary(2008)的断点检验;实验效应发生在我们假定的断点处,而不是其他断点处,这对应着安慰剂检验(Placebo Test),在上篇第二部分有展示;实验变量仅仅对我们关心的结果变量有影响,但是对其他前定变量无影响,其实就是检验断点附近前定变量的连续性。

Estimation是对因果效应的估计,又分为参数法(Global Regression)和非参数法(Local Linear Regression),后者对应着不同带宽的选择。

Sensitivity Checks是排除结果对的模型依赖性(Model Dependency)主要是对不同估计方法、带宽选择以及模型中多项式次数的鲁棒性检查,详见上篇推文的第二部分。

当前有三个R语言包可以实现RDD,Thoemmes详细比较了三个包在以上三方面的异同,并归纳如下表。

综合比较而言,rdd的上手成本是最低的也是最基本的选择,如果你熟悉AER,sandwich这几个包的话,那几乎零成本。 rdrobust 在带宽选择和画图方面具备优势,是唯一个输出各类带宽选择及其置信区间的包,当然也是因为这个包CCT开发的。rddtools的强项在于可以自动进行预设与敏感性检查,它可以输出不同带宽选择的估计结果,还可以自动进行安稳剂检验,这是其他包不具备的。如果对于R语言比较陌生的新手,可以选择rddapp这个带有界面的包进行操作。

作者使用一个数据实例展示了三个包联合使用的效果,这里简单归纳一下。

首先展示一下配置变量与结果变量散点图,然后是三步实际操作。

1 第一步:预设检查

(1)断点检验

(2)安慰剂检测

(3)其他前定变量检测

没有画图,文中直接汇报了检验的p值

2 第二步:估计

3 第三步:敏感测试

借着这个图多说一句,带宽的选择实际上是Bias与显著性的权衡取舍,BW越小越无偏,但是也意味着SE会更大,从而导致越发不显著

当然目前还有很多是这几个R包实现不了的,作者列举了两个,一是多个配置变量的估计,二是关于RDD统计解释力(Statistical Power)的估计。

上述步骤实现的R代码如下:

#### PREPERATION ####

library(ggplot2)

library(dplyr)

library(rdd)

library(rddtools)

library(rdrobust)

# set working directory to file location

setwd("C:\\Users\\fjt36-admin\\Dropbox\\WORK\\2016 Winter Cornell\\rdd software jebs")

# read Stata Dataset generated by "./ICPSR_04091/DS0001/04091-0001-Setup.do"

dat = foreign::read.dta(’ICPSR_04091/ICPSR_04091.dta’)

#distribution of treatment, and treatment effect from randomized experiment

xtabs( ~ DC_TRT, dat)

lm_rct1 = lm(SBIQ48 ~ DC_TRT, dat)

summary(lm_rct1)

#treatment effect of randomized experiment interacted with mother’s IQ at time 0

#IQ is centered to provide average treatment effect

lm_rct2 = lm(SBIQ48 ~ DC_TRT * scale(MOMWAIS0), dat)

summary(lm_rct2)

#subset data to create artifical sharp RDD

#here assuming that only mothers with an IQ lower than the median IQ (85) are

#selected for the treament

dat_s = filter(dat,

(MOMWAIS0 >= median(MOMWAIS0) & !DC_TRT) |

(MOMWAIS0 < median(MOMWAIS0) & DC_TRT),!is.na(SBIQ48))

#table to confirm RDD

table(dat_s$DC_TRT, dat_s$MOMWAIS0)

table(dat_s$DC_TRT)

#graphical inspection of all data and then data of only the sharp RDD, here using

#loess smoother with no binning

dat$DC_TRT_LAB <- factor(dat$DC_TRT, labels = c("Control", "Treatment"))

dat_s$DC_TRT_LAB <-

factor(dat_s$DC_TRT, labels = c("Control", "Treatment"))

p1 <- ggplot(dat) +

aes(

x = MOMWAIS0,

y = SBIQ48,

group = DC_TRT_LAB,

color = DC_TRT_LAB,

shape = DC_TRT_LAB

) +

geom_point(aes(shape = DC_TRT_LAB), size = 2) +

geom_smooth(method = ’loess’,

formula = y ~ x,

aes(linetype = DC_TRT_LAB)) + theme_bw() + ylab("Child IQ at age 2") +

xlab("Mother’s IQ\n\n(a)") +

xlim(c(60, 110)) + ylim(c(60, 130)) +

scale_colour_manual(values = c("darkgrey", "black")) +

theme(legend.position = "none")

p2 <- ggplot(dat_s) +

aes(

x = MOMWAIS0,

y = SBIQ48,

group = DC_TRT_LAB,

color = DC_TRT_LAB,

shape = DC_TRT_LAB

) +

geom_point(aes(shape = DC_TRT_LAB), size = 2) +

geom_smooth(method = ’loess’,

formula = y ~ x,

aes(linetype = DC_TRT_LAB)) + theme_bw() + ylab("Child IQ at age 2") +

xlab("Mother’s IQ\n\n(b)") + xlim(c(60, 110)) + ylim(c(60, 130)) +

scale_colour_manual(values = c("darkgrey", "black")) +

theme(legend.title = element_blank()) +

scale_shape_discrete(

name = "DC_TRT",

breaks = c("0", "1"),

labels = c("Treatment", "Control")

)

multiplot(p1, p2, cols = 2)

#naive treatment effect from RDD data

lm_naive = lm(SBIQ48 ~ DC_TRT, dat_s)

summary(lm_naive)

#RDD effect using global, parametric approach "by hand" without any package

lm_rct3 = lm(SBIQ48 ~ DC_TRT * scale(MOMWAIS0), dat_s)

summary(lm_rct3)

#### "rdd" package ####

#McCrary sorting test as implemented in RDD

rdd::DCdensity(dat_s$MOMWAIS0, median(dat$MOMWAIS0), ext.out = TRUE)

# M1, using defaults

lm_rdd = rdd::RDestimate(SBIQ48 ~ MOMWAIS0, dat_s,

cutpoint = median(dat$MOMWAIS0))

summary(lm_rdd)

#plot of RDD as implemented in RDD

plot(lm_rdd)

#single non-outcome covariate test

lm_rdd_nonoutcome = rdd::RDestimate(APGAR5 ~ MOMWAIS0, dat_s,

cutpoint = median(dat$MOMWAIS0))

summary(lm_rdd_nonoutcome)

#### "rdrobust" package ####

# M2

llm_rdrobust1 = rdrobust::rdrobust(dat_s$SBIQ48, dat_s$MOMWAIS0,

c = median(dat$MOMWAIS0))

print(llm_rdrobust1)

#plot of the RDD as implemented in rdrobust, with addition of confidence interval

rdrobust::rdplot(dat_s$SBIQ48,

dat_s$MOMWAIS0,

c = median(dat$MOMWAIS0),

ci = 95)

# M3

bw = rdrobust::rdbwselect_2014(dat_s$SBIQ48,

dat_s$MOMWAIS0,

c = 85,

bwselect = ’IK’)

llm_rdrobust2 = rdrobust::rdrobust(

dat_s$SBIQ48,

dat_s$MOMWAIS0,

c = median(dat$MOMWAIS0),

h = bw$bws[1],

b = bw$bws[2]

)

print(llm_rdrobust2)

# M4

llm_rdrobust3 = rdrobust::rdrobust(dat_s$SBIQ48,

dat_s$MOMWAIS0,

c = median(dat$MOMWAIS0),

h = lm_rdd$bw[1])

print(llm_rdrobust3)

#### "rddtools" package ####

dat_rddtools = rddtools::rdd_data(

y = SBIQ48,

x = MOMWAIS0,

data = dat_s,

cutpoint = median(dat$MOMWAIS0)

)

# M5

llm_rddtools = rddtools::rdd_reg_np(dat_rddtools)

print(llm_rddtools)

# rddtools uses the same density test and plot as rdd

# (call DCDensity from rdd package)

rddtools::dens_test(llm_rddtools)

#default plot of rddtools package

plot(llm_rddtools)

#the default behavior of plotPlacebo() triggers a error, due to NA returned from

# the recalculations of bw by rddtools::rdd_bw_ik()

rddtools::plotPlacebo(llm_rddtools,

same_bw = T,

from = .25,

to = .75)

#sensitivity to bandwidth choice

rddtools::plotSensi(llm_rddtools,

from = 50,

to = 2,

by = -1)

# M6

lm_rddtools1 = rddtools::rdd_reg_lm(dat_rddtools)

print(lm_rddtools1)

# M7

lm_rddtools2 = rddtools::rdd_reg_lm(dat_rddtools,

bw = rddtools::rdd_bw_ik(dat_rddtools))

print(lm_rddtools2)

# M8

lm_rddtools3 = rddtools::rdd_reg_lm(dat_rddtools, bw = lm_rdd$bw[1])

print(lm_rddtools3)

#### "rddapp" package ####

#M9

#this is assuming that the beta version of rddapp is installed - request from authors

lm_rddapp = rddapp::RDestimate(SBIQ48 ~ MOMWAIS0, dat_s,

cutpoint = median(dat$MOMWAIS0))

summary(lm_rddapp)

计量经济圈是中国计量第一大社区,我们致力于推动中国计量理论和实证技能的提升,圈子以海内外高校研究生和教师为主。我们已经建立了计量经济圈社群,受到海内外高校研究生群体的欢迎,大家在里面分享前沿计量资料和热烈讨论各种计量方法。只要能够沉下心来积淀一段时间,我们相信这是对你的研究工作是大有裨益的,欢迎的你加入到咱们这个大家庭戳这里)。进去之后一定要看“群公告”,不然接收不了群息,也不知道怎么进入咱们的微信群和计量论坛。


帮点击一下下面的小广告,谢谢支持!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
2-0晋级!中国女网18岁1米81新星崛起:郑钦文王欣瑜后继有人

2-0晋级!中国女网18岁1米81新星崛起:郑钦文王欣瑜后继有人

李喜林篮球绝杀
2026-05-31 21:00:21
直到伊朗下令轰炸美空军基地,全世界才惊觉,中国有句话说得很对

直到伊朗下令轰炸美空军基地,全世界才惊觉,中国有句话说得很对

锅锅爱历史
2026-05-31 16:08:36
瑞典将向乌克兰交付36架“鹰狮”

瑞典将向乌克兰交付36架“鹰狮”

参考消息
2026-05-31 15:02:22
记者:丹尼尔去城市集团总部,肯定说了不少陈涛的“好话”

记者:丹尼尔去城市集团总部,肯定说了不少陈涛的“好话”

懂球帝
2026-06-01 12:37:12
41岁王珞丹现状:住河北深山,不结婚不生子,放弃荣华富贵图啥?

41岁王珞丹现状:住河北深山,不结婚不生子,放弃荣华富贵图啥?

白面书誏
2026-04-20 15:26:26
又现断指计划。某大厂员工被竞对公司出两倍工资挖角,试用期被裁

又现断指计划。某大厂员工被竞对公司出两倍工资挖角,试用期被裁

蚂蚁大喇叭
2026-05-31 16:08:01
5国分5金!国羽1冠1亚大赢家,3大世界冠军输球,日本决赛2连败!

5国分5金!国羽1冠1亚大赢家,3大世界冠军输球,日本决赛2连败!

刘姚尧的文字城堡
2026-06-01 09:02:35
荷兰没料到,闯中国领空这事没完,中方当各国面,让荷兰下不来台

荷兰没料到,闯中国领空这事没完,中方当各国面,让荷兰下不来台

霁寒飘雪
2026-06-01 14:45:21
新材料龙头来了,今日申购!A股又见“大肉签”

新材料龙头来了,今日申购!A股又见“大肉签”

21世纪经济报道
2026-06-01 08:50:57
中国没给面子,普京回国后沉默一周认清现实,终究找上哈萨克斯坦

中国没给面子,普京回国后沉默一周认清现实,终究找上哈萨克斯坦

聚焦真实瞬间
2026-05-31 02:19:21
信号失联、烧成火球!神舟21号航天员返回途中,画面捏把冷汗?

信号失联、烧成火球!神舟21号航天员返回途中,画面捏把冷汗?

一簌月光
2026-06-01 12:36:12
这游戏火到被Steam警告:服务器撑不住了

这游戏火到被Steam警告:服务器撑不住了

奶凶的小霸王
2026-06-01 10:08:32
花椒立大功?浙大研究发现:花椒可在36小时清除70%老化细胞?

花椒立大功?浙大研究发现:花椒可在36小时清除70%老化细胞?

宝哥精彩赛事
2026-06-01 14:55:57
当了酒店前台才知道的秘密!瓜太多了,吃不过来了!

当了酒店前台才知道的秘密!瓜太多了,吃不过来了!

夜深爱杂谈
2026-05-27 07:50:31
突发,SK海力士工厂发生火灾

突发,SK海力士工厂发生火灾

半导体行业观察
2026-06-01 11:41:03
面试官:说一下 Agent 的常见范式

面试官:说一下 Agent 的常见范式

新浪财经
2026-05-31 10:41:28
油价大跌超500元/吨,今年“最大油价下跌”后,6月4日油价再大降

油价大跌超500元/吨,今年“最大油价下跌”后,6月4日油价再大降

油价早知道
2026-05-30 00:57:42
拒认亲父,舅舅就是亲爹,两年接18部剧为母买豪宅,后来她咋样了

拒认亲父,舅舅就是亲爹,两年接18部剧为母买豪宅,后来她咋样了

手工制作阿歼
2026-06-01 11:55:27
他从兵团司令员降为军长,55年授衔毛主席怒斥道:他不可不授上将

他从兵团司令员降为军长,55年授衔毛主席怒斥道:他不可不授上将

鹤羽说个事
2026-05-26 22:53:56
战局彻底大变天!俄军节节败退,五月战损远超动员人数

战局彻底大变天!俄军节节败退,五月战损远超动员人数

玲儿爱唱歌
2026-05-28 13:40:23
2026-06-01 16:36:49
计量经济圈
计量经济圈
经济、金融等相关问题
338文章数 155关注度
往期回顾 全部

头条要闻

天涯社区重启 推出1999元"新天涯创世成员产品服务包"

头条要闻

天涯社区重启 推出1999元"新天涯创世成员产品服务包"

体育要闻

哭过之后,文班亚马想给波波维奇打电话

娱乐要闻

奚梦瑶婚礼现场图!一双儿女当花童

财经要闻

网红驱蚊产品,标注化妆品竟含农药成分

科技要闻

关停三年后,天涯社区今起开放访问

汽车要闻

零跑5月交付超8万台再创纪录 全新C10、C11、C16即将焕新上市

态度原创

健康
数码
旅游
公开课
军事航空

尝试干细胞疗法如何避免踩坑?

数码要闻

RTX Spark处理器亮相:英伟达把数据中心搬上了书桌

旅游要闻

逛故宫的游客注意了,坤宁宫明起检修请绕行

公开课

李玫瑾:为什么性格比能力更重要?

军事要闻

韩国最大军工企业爆炸 已造成5人死亡

无障碍浏览 进入关怀版