第27章 合成控制DID和断点回归

本章延续聚焦不可观测变量自选择下的因果推断内容,为本系列内容的收尾章节。上一章我们探讨了双重差分(DID)及其拓展方法,包含搭载双重机器学习的DID,这类方法用于在不可观测混杂容易带来估计偏误时识别处理效应。在已有理论基础之上,我们扩充因果推断工具集,新增能够构建更灵活、由数据驱动生成反事实的相关方法。

本章首先介绍一类分析手段:在观测面板数据场景下,依托未处理单元的信息显性测算反事实结果。该类方法从原始合成控制法(SCM)出发,拓展出广义合成控制(GSCM)、增广合成控制(ASCM)以及合成双重差分(SDID);当平行趋势等传统DID的基准假设难以成立时,它们可以作为备选研究方案。这类方法的核心逻辑为:通过对控制单元、时间周期进行灵活加权,拟合出处理单元未接受干预时的结果变动轨迹。在无法落地随机试验、处理单元样本数量有限的政策评估、外生冲击与干预项目研究中,该类方法的应用规模持续扩大。本节将逐个介绍各项方法,梳理其识别假设、估计思路与现实应用场景。

本章末尾介绍断点回归设计(RDD),这是利用处理分配里清晰或模糊临界阈值的优质准实验方法。依托最少的前提条件,RDD能够在断点附近输出可信的因果估计,也是现阶段应用范围最广的非实验研究设计之一。我们梳理清晰断点、模糊断点两套RDD分析框架,探讨带宽选择、函数形式设定等实操层面的估计问题,并搭配模拟案例夯实核心知识点;同时介绍融合机器学习工具完成协变量调整、方差缩减的前沿延伸内容。读完本章,读者能够全面掌握针对不可观测自选择问题的高阶设计类方法,兼顾结构化建模方案与灵活的数据自适应技术。全章反复沿用本书前文的工具与概念,涵盖机器学习估计量、面板数据结构、局部估计,说明上述内容如何融入这些高阶因果推断设计。

27.1 合成控制法

在实证经济学及相关领域中,识别干预可靠的因果效应时常面临一大难题:缺少有效的反事实样本。随机试验虽是因果推断的理想方案,但在大范围政策场景里几乎难以落地。合成控制法(SCM)由\(Abadie \space \& \space Gardeazabal(2003)\)提出,后续经\(Abadie、Diamond \space \& \space Hainmueller(2010、2015)\)拓展完善,为这类问题提供了一套透明、数据驱动的分析思路。SCM通过构造合成控制单元——即多个未处理单元的加权平均结果,拟合出处理单元在未实施干预条件下本该呈现的结果变化路径。

SCM尤其适用于单一个体(如单个国家、地区)接受干预的案例研究,这类场景下没有任意单个备选单元可以充当合格反事实。该方法不会主观挑选对照组,而是测算多个控制单元的权重,让合成控制组在干预前特征(包含滞后结果与相关协变量)上和处理单元实现匹配。若干预前期拟合效果良好,那么处理单元与合成控制组在干预后的结果差值就可以被解释为因果效应。

不同于双重差分类方法,SCM无需依托平行趋势假设,它直接构造反事实、最小化干预前期的数据偏差。由于SCM大多仅针对单个处理单元开展研究,传统统计推断方法不再适用;因此SCM采用安慰剂检验:依次把每个控制单元假想为处理单元重复建模,生成安慰剂效应分布。若真实测算的处理效应相较于该分布极端偏大,就能够支撑因果解释成立。

SCM的实证结果一般通过时序对比图展示:绘制处理组与合成控制组的结果走势或是二者的差值曲线。若前期拟合紧密、后期走势出现明显分化,图表可以直观有力地佐证政策效果;学界常使用干预后/干预前均方预测误差比值(MSPE)评判效应强弱。

SCM的核心特点是主动构造反事实而非被动假定反事实成立:在干预落地前,利用控制单元的凸组合精准复刻处理单元的各项特征,因此在仅有单个处理单元、无法开展随机分配的场景里实用性极强。

简化版估计步骤

SCM依托面板数据开展分析,数据包含一个处理单元与若干未处理单元的多期观测。假设平衡面板一共包含\(J+1\)个单元、\(T\)个时期,\(1\)号单元自\(T_0+1\)期起接受干预,剩余\(J\)个单元作为备选控制组。记\(Y_{it}^N\)为单元\(i\)\(t\)期未受干预的潜在结果,\(Y_{it}^I\)为受干预后的潜在结果;\(t\le T_0\)时所有单元均满足\(Y_{it}=Y_{it}^N\)\(t>T_0\)时处理单元满足\(Y_{1t}=Y_{1t}^I\)。处理效应定义为: \[\alpha_{1t}=Y_{1t}^I-Y_{1t}^N,\quad t>T_0 \tag{27.1}\] 研究目标是估计\(Y_{1t}^N\)(处理单元若无干预的反事实结果),进而得到\(\alpha_{1t}\)SCM通过对\(J\)个控制单元结果加权得到反事实: \[\hat Y_{1t}^N=\sum_{j=2}^{J+1}w_jY_{jt},\quad t=1,\dots,T \tag{27.2}\] 权重\(w_j\)非负且权重之和等于\(1\),保证合成控制是控制组的凸组合,兼具可解释性、规避外推问题。最终估计处理效应: \[\hat \alpha_{1t}=Y_{1t}-\hat Y_{1t}^N \tag{27.3}\]

想要保证SCM结果可信,需要满足三项前提:

  1. 处理单元的各项特征落在控制单元特征构成的凸包内部,保证可被精准拟合;

  2. 不存在预期效应,即干预落地前政策不会影响结果;

  3. 无溢出干扰,处理仅作用于目标单元、不会波及其他控制单元。

SCM最经典、引用最广泛的实证应用是\(Abadie \space \& \space Gardeazabal(2003)\)针对巴斯克地区恐怖活动经济影响的研究。R语言Synth包内置该案例数据集,使用者可以复现、深入学习这套方法,也是入门SCM的经典实操范例。 研究思路:对比巴斯克地区实际人均GDP走势,与由西班牙其他未受恐怖袭击省份加权合成的对照组人均GDP走势;借助教育、投资、人口等指标让合成组在干预前和巴斯克经济走势对齐,以此对比\(1970\)年恐怖活动升级后的经济差异。

library(Synth)
##
## Synth Package: Implements Synthetic Control Methods.
## See https://web.stanford.edu/~jhain/synthpage.html for additional information.
data(basque) # 载入数据
# 设置时间区间
pre_period <- 1960:1969
post_period <- 1970:1997
# 数据预处理
dataprep.out <- dataprep(
  foo = basque,
  predictors = c("school.illit", "school.prim", "school.med","school.high", "invest", "popdens"),
  predictors.op = "mean",
  time.predictors.prior = pre_period,
  special.predictors = list(
    list("gdpcap", 1960:1969, "mean"),
    list("popdens", 1969, "mean")
  ),
  dependent = "gdpcap",
  unit.variable = "regionno",
  time.variable = "year",
  treatment.identifier = 17,
  controls.identifier = setdiff(unique(basque$regionno), 17),
  time.optimize.ssr = pre_period,
  time.plot = 1955:1997
)

 Missing data- treated unit; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data- treated unit; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.illit ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.illit ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.illit ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.illit ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.prim ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.prim ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.prim ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.prim ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.med ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.med ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.med ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.med ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.high ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.high ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.high ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: school.high ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: invest ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: invest ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: invest ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: invest ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 1 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 2 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 3 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 4 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 5 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 6 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 7 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 8 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 9 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 10 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 11 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 12 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 13 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 14 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 15 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 16 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1960 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1961 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1962 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1963 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1964 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1965 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1966 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1967 
 We ignore (na.rm = TRUE) all missing values for predictors.op.

 Missing data - control unit: 18 ; predictor: popdens ; for period: 1968 
 We ignore (na.rm = TRUE) all missing values for predictors.op.
synth.out <- synth(dataprep.out)
synth.out
$solution.v
            school.illit school.prim school.med school.high      invest
Nelder-Mead    0.2138714 0.000520268  0.1750616   0.1046721 0.000255353
              popdens special.gdpcap.1960.1969 special.popdens.1969
Nelder-Mead 0.1830868                0.2255188           0.09701377

$solution.w
       w.weight
1  6.923761e-06
2  5.967760e-05
3  1.088306e-04
4  1.243924e-06
5  3.979917e-01
6  8.631868e-03
7  1.704100e-01
8  7.672654e-05
9  1.016665e-04
10 3.830440e-05
11 1.292049e-04
12 9.696616e-05
13 1.089988e-04
14 4.219511e-01
15 1.152630e-04
16 1.075580e-04
18 6.396474e-05

$loss.v
            17
17 0.005407202

$loss.w
           w.weight
w.weight 0.00390471

$custom.v
NULL

$rgV.optim
$rgV.optim$out.list
                   p1            p2        p3         p4            p5
Nelder-Mead 0.2443365 -0.0005943781 0.1999984 0.11958216 -0.0002917269
BFGS        0.1151874  0.0889909127 0.1339386 0.09075047  0.0011372402
                     p6       p7          p8       value fevals gevals niter
Nelder-Mead  0.20916670 0.257643  0.11083298 0.005407202    385     NA    NA
BFGS        -0.04013019 2.767943 -0.04013019 0.005414897     41     15    NA
            convcode kkt1 kkt2 xtime
Nelder-Mead        0   NA   NA  0.77
BFGS               0   NA   NA  0.89

$rgV.optim$par
                   p1            p2        p3        p4            p5        p6
Nelder-Mead 0.2443365 -0.0005943781 0.1999984 0.1195822 -0.0002917269 0.2091667
                  p7       p8
Nelder-Mead 0.257643 0.110833

$rgV.optim$value
[1] 0.005407202
# 绘制处理组与合成控制时序图
path.plot(
  synth.res = synth.out, 
  dataprep.res = dataprep.out,
  Main = "巴斯克地区:实际 vs 合成人均GDP",
  Ylab = "人均GDP", 
  Xlab = "年份"
)

# 绘制政策差值(处理效应)图
gaps.plot(
  synth.res = synth.out, 
  dataprep.res = dataprep.out, 
  Main = "差值(巴斯克-合成对照组)", 
  Ylab = "GDP差值"
)

rm(list = ls())

运行结果一般输出两张核心图表:第一张展示真实人均GDP与合成对照组GDP的时序变化,理想状态下干预前两条曲线高度重合;第二张展示两组数据的差值(即估计的处理效应),体现恐怖活动加剧后巴斯克地区相对合成对照组出现明显GDP下滑。干预前期高度匹配赋予结论可信度,后期走势分化直观体现政策冲击。

该案例完整演示了SCM构造反事实、测算处理效应、可视化结果的全流程,也凸显方法优势:透明度高、对函数形式约束少,适配单次、区域性干预政策评估。

想要落地SCM或拓展方法应用的读者,可以参考脚注文献获取完整实操指南与可复现代码。本章后续会介绍SCM的前沿拓展,而脚注所列资料是入门、落地该方法的实用基础。

SCM现已大量用于单处理单元场景下的政策变革、外生冲击与干预评估研究: \(Abadie \space \& \space Gardeazabal(2003)\)使用SCM量化恐怖主义对巴斯克地区经济的冲击,发现相较于无恐怖活动的合成西班牙,当地人均GDP显著下行;在公共政策领域,\(Abadie、Diamond \space \& \space Hainmueller(2010)\)分析加州控烟法案,证实当地吸烟率相较合成控制组大幅回落;\(Cavallo \space et \space al.(2013)\)探究自然灾害的宏观经济后果,发现地震等重大灾害会带来长期显著的负面经济冲击;\(Bohn \space et \space al. (2014)\)借助SCM研究移民执法政策,发现严苛执法并未降低暴力犯罪;卫生领域中,\(Kreif \space et \space al. (2016)\)评估英国医疗改革,证实改革地区相较合成对照组医疗绩效明显改善。依托SCM基础框架,学界衍生出广义合成控制法(GSCM)等拓展模型,更好适配多处理单元、不可观测异质性与时变混杂变量的实证场景。

27.1.1 广义合成控制法

在合成控制法(SCM)的理论基础之上,广义合成控制法(GSCM)拓展模型适用场景,可处理多处理单元、不可观测异质性与时变混杂变量问题。该方法由\(Xu(2017)\)提出,依托R语言gsynth包落地实现,相比传统SCM可以适配更复杂的处理结构。想要深入探究方法原理与实操细节,可参考原始论文与配套文档。

传统SCM在干预前期对控制单元加权以拟合处理单元特征,而GSCM依托含交互固定效应的矩阵补全框架开展建模。该方法将潜在结果拆解为潜在因子、单元固定效应与时间固定效应的组合,能够灵活吸纳不可观测个体异质性和时变趋势。估计算法迭代求解潜在因子,对比真实观测结果与模型预测的反事实结果得到处理效应。GSCM支持多处理单元、交错实施政策、动态效应测算,附带交叉验证工具筛选最优因子数量,同时配套标准误计算与统计推断相关选项。

library(gsynth)
## v1.4.0: estimator='ife' now uses the EM algorithm; default is 'gsynth'. See ?gsynth.
## Since v.1.3.0, *gsynth* is a wrapper of the *fect* package.
data(gsynth)
out <- gsynth(
  Y ~ D + X1 + X2, 
  data = simdata,
  index = c("id", "time"),
  force = "two-way",
  CV = TRUE, 
  r = c(0, 5),
  se = TRUE, 
  inference = "parametric",
  nboots = 1000, 
  parallel = FALSE
)
Cross-validating ...
Criterion: Mean Squared Prediction Error
Interactive fixed effects model...
Cross-validating ...
r = 0; sigma2 = 1.84865; IC = 1.02023; PC = 1.74458; MSPE = 2.07747
*
r = 1; sigma2 = 1.51541; IC = 1.20588; PC = 1.99818; MSPE = 2.22864
r = 2; sigma2 = 0.99737; IC = 1.16130; PC = 1.69046; MSPE = 1.71797
*
r = 3; sigma2 = 0.94664; IC = 1.47216; PC = 1.96215; MSPE = 2.24515
r = 4; sigma2 = 0.89411; IC = 1.76745; PC = 2.19241; MSPE = 1.99413
r = 5; sigma2 = 0.85060; IC = 2.05928; PC = 2.40964; MSPE = 2.32207
  [cv.rule = 1se] r.cv adjusted from 2 to 0 (1-SE band)

 r* = 0
Parametric Bootstrap (para.error = "empirical") 

Simulating errors ...
Can't calculate the F statistic because of insufficient treated units.
# 绘制平均处理效应
plot(out)

# 绘制处理效应差值
plot(out, type = "gap", ylim = c(-3, 12), xlab = "Period",main = "Simulation GSynth Plot")

本次模拟数据集simdata包含\(50\)个单元、\(30\)期观测,其中\(5\)个单元从第\(21\)期起接受政策干预。协变量\(X_1\)\(X_2\)与处理标识\(D\)共同解释被解释变量\(Y\)。模型采用双向固定效应设定,通过交叉验证筛选潜在因子个数。参数估计完成后,借助内置绘图函数可视化结果:第一张图展示逐期平均处理效应,第二张图呈现处理单元实际结果与反事实预测结果的差值。借助两张可视化图表,研究者可以判断处理效应的动态变化与统计显著性。

当处理单元数量较多、各单元政策落地时点不一致时,GSCM具备突出优势。该方法可以刻画不可观测异质性、捕捉复杂时序变动,是适配现代面板数据研究、稳健可靠的SCM拓展方案。

GSCM基础上进一步衍生出增广合成控制法(ASCM),该方法融合传统SCM思路与结果回归建模,优化干预前期拟合效果、降低外推偏误。

27.1.2 增广合成控制法

增广合成控制法(ASCM)在传统合成控制法(SCM)框架基础上引入结果建模,优化干预前期拟合效果、缩减潜在外推偏误。该方法由\(Ben-Michael、Feller \space \& \space Rothstein(2021)\)提出,融合SCM与参数/半参数模型(常用岭回归)构造反事实结果即便处理单元落在控制单元特征凸包外侧也能稳健测算,弥补了传统SCM的核心短板:当控制单元凸组合无法复刻处理单元干预前走势时,SCM拟合失效。

\(Y_{it}\)为单元\(i\)\(t\)期的观测结果,\(1\)号单元自\(T_0+1\)期起接受干预,目标是测算\(t>T_0\)时段的反事实结果\(Y_{1t}^N\)。和SCM一致,ASCM依靠控制组加权构造反事实: \[\hat Y_{1t}^N=\sum_{j=2}^{J+1} w_j^{{ascm}}Y_{jt} \tag{27.4}\]其中\(w_j^{{ascm}}=w_j^{{scm}}+w_j^{{adj}}\)\(w_j^{{scm}}\)SCM权重,作用是最小化干预期前处理单元与合成组的结果偏差;\(w_j^{{adj}}\)为调整项,依托带罚则的残差回归得到。传统SCM限定权重\(w_j\ge0\)且权重和为1,ASCM放宽该约束,允许负权重、权重大于\(1\),凭借灵活性提升预测精度,但代价是模型可解释性有所下降。最终处理效应估计: \[\hat \alpha_{1t}=Y_{1t}-\hat Y_{1t}^N,\quad t>T_0 \tag{27.5}\]ASCM依托安慰剂检验计算标准误与置信区间实现统计推断;通过对干预前期残差建模并纳入后期反事实预测,在传统SCM前期拟合较差时仍能得到精准稳健的效应估计。该方法依托Raugsynth实现,支持岭回归增广建模、结果可视化与敏感性检验。

ASCMSCM的优质拓展,保留原方法透明性,同时依托模型增广获得建模灵活性,尤其适配SCM加权后仍存在前期特征失衡的实证场景。 ASCM提供两类主流实现函数:singlesynth适配单处理单元,依靠控制单元加权+岭修正构造反事实;multisynth拓展至交错处理场景。augsynth包同时搭载两类函数,使用者可根据研究里处理单元数量与政策落地结构灵活选用。

我们以堪萨斯州\(2012\)年个税减税政策举例演示ASCM,使用augsynth内置数据集。被解释变量为各州人均GDP对数lngdpcapita,样本是\(1990-2016\)年季度面板;堪萨斯州在\(2012\)年二季度大幅下调个税,我们评估该政策对地区经济表现的因果影响。 首先拟合基准SCM(代码略),仅用干预前结果构造反事实;随后引入岭回归增广,运行ASCM

library(augsynth)

data(kansas)

# 基准SCM
syn <- augsynth(lngdpcapita ~ treated, fips, year_qtr, kansas, progfunc = "None", scm = TRUE)
One outcome and one treatment time found. Running single_augsynth.
plot(syn)
Plotting augsynth objects with inf=TRUE may be slow. For faster results, first create a summary object and plot that object directly (e.g., s <- summary(augsynth_obj); plot(s)).

# 岭增广ASCM
asyn <- augsynth(lngdpcapita ~ treated, fips, year_qtr, kansas, progfunc = "Ridge", scm = TRUE)
One outcome and one treatment time found. Running single_augsynth.
# 绘制结果图
plot(asyn)
Plotting augsynth objects with inf=TRUE may be slow. For faster results, first create a summary object and plot that object directly (e.g., s <- summary(augsynth_obj); plot(s)).

ASCM通过修正堪萨斯州与合成对照组的残差差值优化前期拟合,在岭罚项约束下适度突破控制单元凸包做外推;本例中政策后期效应更清晰、置信区间更窄,凸显传统SCM拟合欠佳时ASCM的优势。

针对多时点交错落地政策的场景,augsynth包中multisynth函数可用。典型应用为\(Paglayan(2018)\)研究各州公立工会强制集体谈判法案的政策效应,代码与复现材料在包的Github主页可获取。

近年还有一项SCM拓展研究:引入多结果变量提升估计精度与稳健度。\(Ben-Michael、Feller \space \& \space Sun(2025)\)提出联立多个相关结果建模的分析框架强化因果推断,依托模拟与弗林特水污染对学生成绩的实证重做验证方法,复现资料见脚注。

27.2 合成双重差分法

正如本章前文所述,双重差分(DID)与合成控制(SC)都是测算处理效应的主流方法,二者各有优劣。DID依托平行趋势假设,对全部单元与时期均等赋权;而SC通过最优权重构造处理单元的合成对照组,但忽略固定效应与时序带来的贡献变动。合成双重差分(SDID,由\(Arkhangelsky \space et \space al.(2021)\)提出)在统一框架内融合两种方法的优势,提升估计稳健性、优化干预前期拟合效果、降低外推偏误。

SDID同时在单元维度、时间维度设置权重实现上述优化:单元权重参照SC思路依托干预前数据求解,时间权重借鉴DID思想利用全期(干预前+干预后)数据拟合。该结构可灵活适配异质性环境,在实证中拥有更优的估计表现。

简化估计步骤

假设平衡面板一共包含\(N\)个单元、\(T\)个时期,政策自\(T_0+1\)期落地,此处仅设定单个处理单元。结果设定为: \[Y_{it}=\mu+\alpha_i+\beta_t+W_{it}\tau+\varepsilon_{it} \tag{27.6}\]式中\(\mu\)为总体均值,\(\alpha_i\)是单元固定效应,\(\beta_t\)是时间固定效应,\(W_{it}\)为二元处理标识,\(\tau\)代表处理效应,\(\varepsilon_{it}\)是特异扰动项。

SDID通过极小化双重加权最小二乘准则,求解参数\(\hat\tau,\hat\mu,\hat\alpha,\hat\beta\)\[(\hat\tau^{{sdid}},\hat\mu,\hat\alpha,\hat\beta)=\arg\min_{\tau,\mu,\alpha,\beta}\sum_{i=1}^N\sum_{t=1}^T \big(Y_{it}-\mu-\alpha_i-\beta_t-W_{it}\tau\big)^2\cdot \hat\omega_i^{{sdid}}\cdot \hat\lambda_t^{{sdid}} \tag{27.7}\] \(\hat\omega_i^{sdid}\)\(\hat\lambda_t^{sdid}\)分别是单元权重、时期权重的估计值。从模型构造能看出SDIDDiDSC的广义形式:若两类权重全部固定均等,则目标函数退化为双向固定效应回归,等价于传统DID(默认全部单元、时期贡献相同,无差异化加权);若剔除单元固定效应与时间权重、仅保留匹配干预前走势的单元权重,则等价于SC。综上DIDSC都是SDID的特例,该方法可灵活对单元、时序加权,同时吸纳个体与时点异质性。

以加州\(1988\)年99号烟草税法案为例,测算政策对香烟消费量的影响,Rsynthdid内置数据集与配套工具:

library(synthdid)

# 测算加州99号法案对香烟消费的政策效应
data('california_prop99')
setup <- panel.matrices(california_prop99)
tau.hat <- synthdid_estimate(setup$Y, setup$N0, setup$T0)
se <- sqrt(vcov(tau.hat, method='placebo'))
sprintf('point estimate: %1.2f', tau.hat)
[1] "point estimate: -15.60"
sprintf('95%% CI (%1.2f, %1.2f)', tau.hat - 1.96 * se, tau.hat + 1.96 * se)
[1] "95% CI (-37.10, 5.89)"
plot(tau.hat)
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
ℹ The deprecated feature was likely used in the synthdid package.
  Please report the issue at
  <https://github.com/synth-inference/synthdid/issues>.

# 分别用SC、DiD单独估计做对比
tau.sc  <- sc_estimate(setup$Y, setup$N0, setup$T0)
tau.did <- did_estimate(setup$Y, setup$N0, setup$T0)
estimates <- list(tau.did, tau.sc, tau.hat)
names(estimates) = c('Diff-in-Diff', 'Synthetic Control', 'Synthetic Diff-in-Diff')
print(unlist(estimates))
          Diff-in-Diff      Synthetic Control Synthetic Diff-in-Diff 
             -27.34911              -19.61966              -15.60383 

对比结果能够看出:平行趋势不成立时,SDID的效应估计相较DID更为保守;前期拟合不理想时,相较SC结果更稳健。图中黑色箭头为SDID测算的平均处理效应,\(1988\)年政策落地后两组走势出现明显分化,体现政策对吸烟率的冲击。整体来看,SDID规避了非平行趋势下DID高估效应、前期失衡下SC结果波动的缺陷。

synthdid包完整落地该方法,配套完备的理论文档与实操示例,官方教程站点:https://synth-inference.github.io/synthdid/,内含教程与复现代码。

针对Stata使用者,\(Clarke \space et \space al.(2024)\)系统梳理SDID方法论,覆盖单时点与交错落地政策场景,开发sdid命令;即便不用Stata,该文献对模型假设、推断思路、实证范例的清晰阐述也极具参考价值。

此外\(Ciccia(2024)\)提出事件研究拓展版SDID,可将总效应拆解为动态逐期效应,适配普通与交错政策场景,对应Statasdid_event

Python侧已有开源实现,项目地址:https://github.com/MasaAsami/pysynthdidhttps://github.com/d2cml-ai/synthdid.py

综上,本节介绍的SCM及其各类拓展,为观测数据构造可信反事实、识别处理效应提供了高效工具,尤其适配处理单元稀缺、缺少天然对照组的研究。但当政策分配依托明确临界阈值、在个体或时间上分层落地时,断点回归设计(RDD)往往更适配。下一节我们围绕RDD的理论基础、估计思路与实证应用展开讲解。

27.3 断点回归设计

断点回归设计(RDD)是一类高效准自然实验分析框架,依托明确规则开展处理分配:个体能否接受处理由连续分配变量是否跨过既定临界值决定。该规则在断点处形成结果跳跃、两组样本无取值重叠,临界值上方个体进入处理组、下方个体归入控制组。在无法开展随机试验,但政策严格依托临界阈值分配处理的场景中,RDD被广泛用于因果效应测算;规范设定下,RDD可以得到断点附近样本具备内部有效性的因果估计,结论可信度媲美随机对照试验(RCT)。

经典设定:政策落地依托个体打分变量是否突破阈值,例如考试分数高于\(75\)分即可申领奖学金。临界值两侧临近样本在可观测、不可观测特征上高度近似,因此结果(升学、收入等)的系统性差异可以归因于政策冲击。

图27.1是奖学金门槛等于\(75\)的明晰断点模拟示例,竖直虚线代表临界值,阴影区间为断点两侧估计带宽\(h\)。断点左右两侧分别拟合一条回归曲线,竖直线段代表断点处的结果跳跃,即政策估计效应。该设计假定断点周边个体其余特征同质,由此对断点处的结果落差做因果解释。

核心逻辑:若断点附近个体具备可比性,观测到的结果差异就来自处理本身;临界位置处个体进入处理组的概率发生骤变。想要保证识别有效,分配规则无需随机,但必须界定清晰、公开透明、无法人为操纵。这类局部对比的前提是个体不能人为操纵分配变量、刻意聚集在断点两侧;若样本可以精准操控取值、扎堆断点,模型内部有效性受损。学界常用\(McCrary(2008)\)密度检验排查人为操纵行为;密度检验可以识别样本堆积,但无法排除依托不可观测变量实现的隐性操纵,该无操纵假设最终需要制度背景佐证。

在无精准操纵前提成立时,断点周边分配近似随机,模型识别局部平均处理效应(LATE),结论仅外推至断点邻域样本。该方法不要求分配变量与被解释变量独立,仅需断点附近分配近似随机;识别依托关键假定:无政策干预时,被解释变量随分配变量在断点处平滑连续变化。

RDD分为明晰断点、模糊断点两类。明晰断点:处理完全由临界值决定,阈值之上全部受处理、之下全部不受,通过对比断点两侧被解释变量条件期望测算效应。模糊断点:处理概率在断点处跃升,但并非严格一刀切(政策执行宽松、个体可自主放弃处理),此时临界标识作为实际处理的工具变量,参考工具变量(IV)思路:用结果跳跃幅度除以处理概率跳跃幅度得到LATE。简言之,明晰断点的处理在阈值处确定性落地,模糊断点仅处理概率发生间断,需要借助工具变量还原因果效应。

在鲁宾因果框架下,个体\(i\)存在两种潜在结果:受处理\(Y_i(1)\)、未受处理\(Y_i(0)\)。处理标识\(D_i\)由分配变量\(X_i\)是否大于临界值\(c\)决定: \[D_i= \begin{cases} 1,\quad X_i\ge c \\ 0,\quad X_i< c \end{cases} \tag{27.8}\] \(D_i\)是关于\(X_i\)的分段间断函数,无论距离\(c\)多近,跨过阈值瞬间处理状态从\(0\)变为\(1\)。断点处局部处理效应: \[\begin{aligned} \tau_{LATE} &= \mathbb{E}[Y_i(1)\mid X_i=c]-\mathbb{E}[Y_i(0)\mid X_i=c] \\ &= \mathbb{E}[Y_i\mid X_i=c,D_i=1]-\mathbb{E}[Y_i\mid X_i=c,D_i=0] \end{aligned} \tag{27.9}\]假定潜在结果的条件期望在\(X\)临近\(c\)时连续,对比断点左右紧邻样本的观测结果即可测算效应。政策带来处理效应时,被解释变量均值会在断点出现跳跃,该跳跃即为因果效应: \[\hat \tau=\lim_{x\downarrow c}\mathbb{E}[Y\mid X=x]-\lim_{x\uparrow c}\mathbb{E}[Y\mid X=x] \tag{27.10}\]第一项是断点右侧(处理组)的期望结果,第二项是左侧(控制组);二者差值剥离出处理的因果作用,该非参数思路无需预设函数形式,仅依托断点邻域局部数据。

模糊断点中,临界值无法完全决定处理状态,仅个体受处理概率在\(X=c\)处突增,依旧可以识别断点局部LATE,但需要修正:部分阈值上方个体未参训、部分下方个体意外参训。 正式设定下处理概率: \[P(D_i=1\mid X_i)= \begin{cases} p_0,\quad X_i<c \\ p_1,\quad X_i\ge c \end{cases},\quad p_1>p_0 \tag{27.11}\]核心逻辑:断点造成参训概率突变;潜在结果在\(X=c\)处连续,则用结果的间断幅度除以处理概率的间断幅度得到政策效应,和工具变量思路等价,临界标识充当实际处理的工具。

估计与实操落地

落地断点回归需要依次敲定多项设定:参数/非参数估计选型、函数形式、带宽选取、断点邻域范围设定,配套绘图、平衡性检验、安慰剂检验等稳健性诊断。研究者需要在偏差与方差间权衡取舍,确定建模方式、带宽、核函数。

参数思路:除断点跳跃外,被解释变量随分配变量平滑变动,明晰断点常用基准设定: \[Y_i=\alpha+\tau D_i+f(X_i-c)+\varepsilon_i \tag{27.12}\] \(Y_i\)为观测结果,\(D_i\)根据\(X_i\ge c\)生成处理虚拟量,\(f(X_i-c)\)刻画分配变量的平滑趋势;系数\(\tau\)捕捉断点处结果跳跃,代表断点局部处理效应。加入平滑项可以剥离原有趋势,纯粹分离政策带来的间断变化。

局部多项式回归是RDD主流估算方法:断点左右分开做多项式拟合,允许截距和斜率全部不同。常用基准为中心化局部一阶线性,令\(\tilde X_i=X_i-c\),模型: \[Y_i=\alpha+\tau D_i+\beta \tilde X_i+\gamma(D_i\cdot \tilde X_i)+\varepsilon_i \tag{27.13}\]\(\tilde X_i\)在断点左侧为负、断点处等于\(0\)、右侧为正;\(D_i\)\(X_i\ge c\)时取\(1\)。该式子在断点两侧拟合两条斜率、截距均可不同的直线。

由于两组样本无取值重叠,效应依靠断点两侧外推得到;函数形式误设会带来外推偏误,因此优先依托断点附近样本、选用灵活数据驱动模型。高阶多项式灵活性更高,但极易过拟合、断点附近结果波动剧烈,学界普遍建议仅使用局部一阶或二次多项式(\(Gelman \space \& \space Imbens,2019\))。标准误一般选用异方差稳健标准误;近年文献不建议按分配变量聚类标准误(\(Calonico \space et \space al.,2017\))。

带宽选取是关键设定,直接左右偏差-方差权衡:带宽越小,样本越贴近断点、偏差下降但样本变少方差抬升;带宽越大,样本变多方差收缩,但纳入远离断点样本带来偏差。主流数据驱动算法:Imbens–Kalyanaraman(IK)以均方误差最优为准则,Calonico–Cattaneo–Titiunik(CCT)附带偏差修正提升稳健性。带宽筛选帮助锁定函数形式最平稳的断点邻域;实证中常更换多组带宽绘图,观察估计值变动做敏感性检验。

非参数核思路:\(f(X_i-c)=f(\tilde X_i)\)依托核加权构造局部均值,权重随到断点距离增加递减;三角核在RDD边界估计中应用最广,既侧重近断点样本又最小化均方误差。该类方法无需全局函数形式,但同样要选定带宽、权衡偏差方差。

函数形式(多项式阶数)同样影响结果:高阶灵活但易过拟合、受异常值扰动;局部一次/二次多项式兼顾拟合优度与可解释性。研究者常绘制拟合曲线、残差图判断模型适配度,决定是否提升多项式阶数。

图像检验是RDD诊断的必备环节:横轴分配变量、纵轴被解释变量,断点两侧分别绘制拟合曲线。直观判断断点处是否存在明显跳跃,同时辅助敲定带宽与函数形式;但图像受分组区间、带宽取值影响,读图需谨慎。

有效性检验需要排除断点附近人为操纵:\(McCrary(2008)\)密度检验核查分配变量在临界处的密度跳跃,R语言依托DCdensity()实现;同时检验各类协变量在断点处是否平滑,若协变量出现间断,大概率存在混杂因素、结论存疑。平衡性检验包含图表、回归两类方案,对比断点周边基线特征;安慰剂检验选取无政策落地的伪临界值,若伪断点依旧显著跳跃则原模型有效性受损。

27.3.1 断点回归模拟

本次模拟复现前文奖学金RDD案例:考试分数高于\(75\)分即可申领奖学金。如前文图示,处理分配在临界值处形成明晰跳跃,依托阈值附近局部样本开展因果推断。初始绘图借助ggplot2手动绘制,本小节依托rdrobust包规范实现RDD建模。rdplot(y, x, c = 0)依托局部线性回归自动生成断点拟合图:\(x\)为中心化后的分配变量,\(y\)是模拟被解释变量;函数对原始数据分组散点展示,并在断点两侧分别拟合多项式曲线,直观查看断点跳跃与模型适配度。

使用rdrobust()测算处理效应,该函数采用\(Calonico、Cattaneo \space \& \space Titiunik(2014)\)提出的带稳健偏差修正与规范推断的局部多项式回归。

  • rdrobust(y, x, c = 0, p = 1, kernel = "triangular", h = ...)代表采用一阶局部线性+三角核(离断点越近权重越高)

  • 带宽\(h\)经由rdbwselectCCT最优带宽、bwselect = "mserd"修正算法筛选。

输出结果包含未修正基准效应、偏差修正后稳健效应与对应标准误;更换\(p=2\)局部二次多项式可对比阶数变动带来的结果敏感性。前文提及,局部线性相较高阶多项式在偏差方差权衡、断点附近稳定性上更具优势。

library(rdrobust)

# 模拟0~100区间考试分数
set.seed(42) # 固定随机种子保证结果可复现
score <- rnorm(1000, mean = 70, sd = 15)
score <- pmin(pmax(score, 0), 100) # 限定分数0~100

# 分数超过75获得奖学金
cutoff <- 75
treated <- ifelse(score > cutoff, 1, 0)
y <- 20 + 30 * treated + 0.8 * score + rnorm(1000, 0, 15) # 生成结果变量
x <- score - cutoff # 分配变量以断点中心化
# CCT准则最优带宽筛选
bw_cct <- rdbwselect(y, x, kernel = "triangular", bwselect = "mserd")
print(bw_cct)
Call: rdbwselect

Number of Obs.                 1000
BW type                       mserd
Kernel                   Triangular
VCE method                       NN

                               Left        Right
Number of Obs.                  647          353
Eff. Number of Obs.             195          149
Order est. (p)                    1            1
Order bias (q)                    2            2
Unique Obs.                     647          333
# 绘制断点拟合图(默认局部线性)
rdplot(y, x, c = 0, kernel = "triangular", p = 1)

# 三角核+局部线性(p=1)断点回归
out <- rdrobust(y, x, c = 0, p = 1, kernel = "triangular", h = bw_cct$bws[1,1])
out$Estimate
       tau.us   tau.bc    se.us    se.rb
[1,] 20.82346 24.46106 3.442885 4.352538
# 三角核+局部二次(p=2)断点回归
out2 <- rdrobust(y, x, c = 0, p = 2, kernel = "triangular", h = bw_cct$bws[1,1])
out2$Estimate
       tau.us   tau.bc    se.us   se.rb
[1,] 24.46106 29.94459 4.352538 5.20353

借助rddensity包的rdplotdensity()绘制第二张图,执行\(McCrary(2008)\)密度检验,排查样本人为操控分配变量、扎堆断点的行为(例如刻意提分拿到奖学金)。RDD核心前提是分配变量无法精准人为操纵,否则断点两侧样本不再同质;rddensity()分别测算断点左右分配变量密度,检验密度是否出现显著跳跃。检验结果显著则说明存在人为筛选和操纵,破坏因果解释;本套模拟数据无人为操纵,检验\(p\)值不显著,契合模型前提。

综上,rdplotrdrobustrdbwselectrddensity整套函数构成RDD完整实操流程,覆盖建模、估计、稳健校验全环节。实证时可按需修改关键设定:调整临界值、更换均匀核/Epanechnikov核、改用IK带宽准则、变换多项式阶数。针对含协变量或模糊断点(处理概率在断点跃升但非完全一刀切)的复杂场景,rdrobust还支持工具变量形式拓展建模。

27.3.2 断点回归的可信度与拓展应用

断点回归(RDD)拥有优秀的内部有效性,但仅能识别断点周边样本的处理效应。明晰断点场景下,对应临界位置的平均处理效应;模糊断点中,识别依从者的局部平均处理效应(LATE),也就是仅因跨过阈值改变自身处理状态的个体。该结果无法代表全样本平均效应,只针对断点邻近群体,这也是LATE里“局部”的含义。取舍关系为:模型识别结论可信,但结论外推范围受限。不过多数场景里,断点周边样本恰好是政策重点关注对象,例如分数线临界处、刚满足医疗救助门槛的人群。RDD需要断点附近充足样本才能精准估计,且依赖界定清晰的分配规则;若断点周边样本稀疏,模型检验力与估计精度下滑,这类场景不适合选用RDD。即便存在上述局限,RDD仍是实证里可信度靠前的非实验因果识别方案,广泛用于各类政策冲击评估。

本小节仅对基础RDD做简要说明,学界已衍生大量突破单临界值、连续分配变量设定的拓展形式:离散型分配变量断点、多临界值与多打分断点(依托rdmulti工具)、地理空间断点(SpatialRD),还有协变量调整、聚类数据、弱识别问题修正等配套方法。\(Calonico \space et \space al.(2025)\)配套rdhte包,开发异质性处理效应的估计与推断流程;\(Hsu \space \& space Shen(2024)\)搭建动态断点框架,适配个体多次触发政策门槛的重复断点场景,相关复现代码可参考文献配套链接。上述拓展内容复杂度偏高,本章不展开详述。实操学习可查阅站点rdpackages.github.io,汇总RStataPython主流配套包、复现数据与示例代码,Cattaneo、Idrobo与Titiunik(2024)的综述文献也收录在此站点。

机器学习逐步融入RDD优化高维协变量调整的估计精度:\(Kreiss \space \& \space Rothe(2024)\)提出两步法,先用局部套索筛选有效协变量,再纳入局部线性RDD建模;该方案在近似稀疏条件下仍可保证推断有效,沿用传统带宽、方差测算工具。

\(Noack、Olma \space \& \space Rothe(2024)\)提出另一种协变量修正思路:借助套索、随机森林、神经网络等机器学习算法拟合协变量对被解释变量的映射,再从结果里剔除该拟合值;该方法适配高维协变量,压缩效应估计方差。模拟结果表明,相较传统RDD,在协变量信息充足时,该方法能得到更窄的置信区间,Python端依托DoubleML包落地实现。

总结:RDD依托宽松前提实现稳健因果识别,优势是逻辑简洁、规则透明:政策严格依托临界值分配、样本无法人为操控分配变量时,仅需极少结构假定即可还原因果。落地难点集中在细节把控:审慎选定带宽、合理设定函数形式、排查人为操纵、严谨解读实证系数,以上环节共同决定RDD实证质量。

注释

  1. 合成控制法(SCM)通过匹配处理单元与控制组加权平均的观测特征、滞后结果求解最优权重\(w_j\)。记\(X_1\)为处理单元\(k\times1\)维干预前预测变量向量,\(X_0\)为控制组同变量构成的\(k\times J\)矩阵。权重\(W\)极小化加权距离: \[\|X_1-X_0W\|_V=\sqrt{(X_1-X_0W)'V(X_1-X_0W)}\] \(V\)是半正定矩阵,用来设定各预测变量的相对重要程度,通常选取使干预前均方预测误差(MSPE)最小的\(V\)。优化问题写作: \[\min_{W}\|X_1-X_0W\|_V \quad \text{s.t. } w_j\ge0,\sum w_j=1\]

  2. Carlos Mendez 编写的SCM实操教程:https://carlos-mendez.quarto.pub/r-synthetic-control-tutorial/SynthCRAN主页:https://cran.r-project.org/web/packages/Synth/index.html,参考Abadie、Diamond、Hainmueller(2011)。上述资源附带包内置示例数据集,完整覆盖数据预处理、建模、绘图与结果解读。

  3. 参考Xu(2017)、Xu & Liu(2022),文献系统梳理广义合成控制法(GSCM)理论、估计细节与实证应用。原gsynth包已整合并入fect包,新版文档与源码:https://yiqingxu.org/packages/fect/01-gsynth.html

  4. 增广合成控制法(ASCM)等价于求解如下优化问题: \[\min_{\beta,w}\sum_{t=1}^{T_0}\Big(Y_{1t}-X_t'\beta-\sum_{j=2}^{J+1}w_jY_{jt}\Big)^2+\lambda\|\beta\|_2^2\]\(X_t\)为时变协变量/潜在因子构成的向量,\(\beta\)为回归系数向量,\(\lambda\)是岭回归罚项系数,用来控制正则化强度;岭罚压缩系数、规避过拟合,同时缓解控制单元凸包外推带来的偏误。

  5. Ben-Michael、Feller、Rothstein(2021)《增广合成控制法》,刊发于Journal of the American Statistical Association,配套Raugsynthhttps://github.com/ebenmichael/augsynth

  6. 复现数据存于哈佛数据文库:Sun、Liyang等人(2025)《借助多结果变量优化合成控制法》,https://doi.org/10.7910/DVN/KBVBF9

  7. 参考Arkhangelsky等人(2021)算法1、2与公式4~6。SDiD权重由两步优化求解: 单元权重: \[(\hat\zeta_0,\hat\omega^{\text{sdid}})=\arg\min_{\zeta,\omega}\sum_{t=1}^{T_{\text{pre}}}\Big(\zeta_0+\sum_{i=1}^{N_{\text{tr}}}\omega_iY_{it}-\frac1{N_{\text{tr}}}\sum_{i=N_{\text{tr}}+1}^NY_{it}\Big)^2+\zeta\|\omega\|_2^2\] 时间权重: \[(\hat\lambda_0,\hat\lambda^{\text{sdid}})=\arg\min_{\lambda}\sum_{i=1}^{N_{\text{tr}}}\Big(\lambda_0+\sum_{t=1}^{T_{\text{pre}}}\lambda_tY_{it}-\frac1{T_{\text{post}}}\sum_{t=T_{\text{pre}}+1}^TY_{it}\Big)^2\] \(\zeta\)为正则系数,用来防范过拟合。

  8. 明晰断点RDD中处理完全由阈值决定:\(P(D_i=1|X_i<c)=0\)\(P(D_i=1|X_i\ge c)=1\),传统基于共同支撑的匹配不适用。

  9. 断点处处理效应: \[\tau=\frac{\lim_{x\downarrow c}\mathbb{E}[Y|X=x]-\lim_{x\uparrow c}\mathbb{E}[Y|X=x]}{\lim_{x\downarrow c}\mathbb{E}[D|X=x]-\lim_{x\uparrow c}\mathbb{E}[D|X=x]}\] 该瓦尔德型估计量识别受阈值影响的依从者局部平均处理效应(LATE)。参数化两阶段最小二乘(2SLS)设定: 一阶段(处理方程): \[D_i=\pi_0+\pi_1\mathbb I(X_i\ge c)+g(X_i-c)+v_i\] 二阶段(结果方程): \[Y_i=\alpha+\tau\hat D_i+f(X_i-c)+\varepsilon_i\] \(\mathbb I(X_i\ge c)\)为工具变量,\(g(\cdot)\)\(f(\cdot)\)是分配变量的光滑函数,\(\hat D_i\)是一阶段拟合值,系数\(\tau\)为断点局部LATE

  10. 明晰断点RDD一般不纳入控制变量:若设计有效,断点两侧样本天然均衡;加入协变量可提升精度,但可能带来残差失衡隐患,模糊断点(处理非严格一刀切)场景下协变量更有必要。协变量调整方法参考Calonico等人(2019)。

  11. 三角核权重随到断点距离线性递减: \[K(u)=(1-|u|)\cdot\mathbb I(|u|\le1)\] 其中\(u=\frac{X_i-c}{h}\)\(c\)是临界值,\(h\)为带宽。

  12. 研究者可绘制\(E[W_i|\tilde X_i,D_i]\)图示(\(W_i\)为前定协变量,\(\tilde X_i=X_i-c\)),同时拟合局部回归: \[E[W_i|\tilde X_i,D_i]=\alpha+\beta_0\tilde X_i+\beta_1(\tilde X_i\cdot D_i)+\tau_W D_i\] \(\tau_W\)显著则代表协变量在断点存在跳跃,样本基线失衡。

  13. 空间断点(SpatialRDD)包说明文档:https://cran.r-project.org/web/packages/SpatialRDD/vignettes/spatialrdd_vignette.html

  14. RDD全套工具主页:https://rdpackages.github.io/