最近一直在做环境经济学里几篇经典论文的复现,其中最值得把全过程写出来的,就是“排污权交易机制是否提高了企业全要素生产率——来自中国上市公司的证据”这个题目。它看起来只是评估一项环保政策的效果,实际上是一套完整的微观计量实战:上市公司财务数据清洗、全要素生产率(TFP)的多种测度、双重差分(DID)模型的设定、平行趋势与安慰剂检验,再加上一堆容易踩进去的暗坑。
这篇文章我把整个复现过程拆成六个部分讲清楚:先从论文骨架和识别策略说起,再讲数据怎么备、TFP怎么算、基准回归怎么做、稳健性和机制怎么加固,最后专门用一节记录复现中真实遇到过的报错和逻辑错误。适合正在复刻类似政策评估论文的同学,也适合想系统入门DID和TFP测算的从业者。读完你不仅能复现这篇,还能把同一套框架迁移到其他“制度或政策冲击对企业绩效影响”的研究上去。
1. 复现之前:先把论文骨架拆干净
1.1 研究问题与政策背景
论文想回答的其实是一个因果推断问题:排污权交易试点政策落地之后,试点地区上市公司的全要素生产率是否显著提升了?注意这里的关键词是“是否”,而不是“相关”。TFP和企业绩效之间天然互相影响,盈利好的公司可能更容易被纳入试点,也可能更有能力应对环保成本,如果只看横截面差异,你分不清是政策带来了生产率提升,还是高生产率企业恰好被选中。这就是所谓的内生性问题。
排污权交易机制的政策逻辑和过去那种“规定排放浓度、限期关停”的命令控制型手段不一样,它是先给企业设定一个排放总量上限,再把排放配额变成可交易的资产。理论上,配额有价格之后,减排成本低的企业会主动多减排并把富余配额卖掉,减排成本高的企业会买配额,最后全社会的减排成本被重新分配,同时市场机制倒逼企业改进生产技术和资源配置。论文的核心贡献就是验证这个理论上说得通的传导链条,在上市公司数据里到底成不成立。
1.2 识别策略的底层逻辑:为什么是DID
这篇论文的识别策略是标准的双重差分(Difference-in-Differences,DID)。它利用的是试点政策在时间和地域上的双重变化:试点不是所有地区同时推开的,也不是某个地区所有年份都处于政策期。于是可以构造两个维度的差异——试点地区和非试点地区的差异(Treat),政策实施前和实施后的差异(Post),两者的交互项就是政策效应。
用反事实框架理解会更直观。对于一家试点地区的上市公司,我们想知道的是:如果当年没有排污权交易政策,它的TFP会是多少?这个反事实观测不到。DID的聪明之处在于,它假设非试点地区的企业在同期经历的变化趋势可以代理试点地区企业“没有政策时的变化趋势”。只要这个平行趋势假设成立,那么试点地区政策前后的TFP变化减掉非试点地区同期TFP变化,剩下的净差异就归因于政策。
这里有个必须注意的前提:政策试点区域的划定不能是随机的,理论上政府会优先选择产业结构和市场化条件较好的地区试点,这会产生“选择偏差”。所以论文通常要在回归里控制企业层面的固定效应和一系列时变特征,尽可能把非随机选择造成的影响挤出去。这也解释了为什么基准回归的设定、固定效应的组合方式,会直接决定结论的靠谱程度。
1.3 复现的产出不只是回归表
很多人以为复现就是把论文里的系数表跑出来,对一遍数字就结束了。我实际操作下来完全不是这个概念。完整的复现至少包含四层产出:
第一,可运行的数据清洗代码,能从原始数据一步步走到回归样本;第二,核心变量的构造过程,尤其是TFP这类不能直接从报表里拿到的指标;第三,基准回归、平行趋势、安慰剂、稳健性、机制检验的完整结果;第四,也是容易被忽略的,是对论文叙事逻辑的还原——作者为什么要这么设定样本区间、为什么要控制这组变量、为什么聚类到这一层。只有这四层全部走通,才算真正复现了一篇论文。
2. 数据准备:整个复现里最耗时的一环
2.1 样本与数据源怎么选
先明确研究对象:A股上市公司,样本区间大致覆盖排污权交易试点启动前后的若干年,一般是从2008年前后到2017年以后。这样设计是为了保证“政策前”有足够长的观测期来检验平行趋势,“政策后”有足够长的区间来捕捉政策的动态效果。
数据源方面,拆成三类:
- 上市公司财务与公司特征数据:主要来自综合金融数据库,或者交易所公开披露整理而成的研究数据库。需要的核心字段包括营业收入、固定资产、员工人数、中间投入或营业成本、总资产、负债、所有者权益、上市年份、行业代码、注册地省份等。
- 上市公司污染排放和环境披露数据:现在各大数据库都有环境信息披露板块,里面是企业环保投入、排污费、排放量等字段,主要用于机制检验和异质性分析。
- 试点政策名单:根据官方公告整理的首批试点区域、扩容区域以及政策起始年份。
一个容易犯的错是直接用数据库给好的“省份代码”去匹配政策,但数据库里有的给出注册地,有的给出办公地,两者在环保政策上可能不一致。注册地决定企业受哪个地区的环保监管,所以论文口径下应该以注册地为准。合并前一定要把地址字段拉出来人工抽检。
2.2 处理组和控制组的划分逻辑
处理组:注册地位于首批排污权交易试点区域内的上市公司。控制组:注册地不在试点区域内、也没有在样本期内被纳入扩容名单的公司。
这里有一个隐藏细节:如果直接把扩容区域的公司放到控制组里,它们在政策后期其实也变成了“处理者”,会污染估计。稳妥做法有两种,一是把扩容区域的公司直接剔除,二是把样本截止时间提前到扩容之前。我复现时选择了前者,并在稳健性部分用后者做了交叉验证。
另外,虽然试点区域是省份层面划定的,但试点往往只在省内部分地级市开展,省内的非试点城市公司属于控制组。如果数据支持精确到地级市,就不要简单用省级虚拟变量,否则会把一部分控制组公司错误地标记成处理组,导致DID估计量向零偏。
2.3 清洗流程清单
我建议把清洗步骤固定成一套可重复执行的脚本,每一步做完都存一个中间文件,不要一口气把所有筛选条件写在大括号里。清洗流程大致是:
- 剔除金融行业公司(银行、保险、证券等),因为这些公司的会计结构特殊,资产和收入口径与一般企业不可比。
- 剔除ST、*ST以及退市整理期的公司,这类公司财务状况异常,TFP测算失真。
- 剔除上市当年的观测值,IPO当年财务数据常被粉饰或异常。
- 剔除核心变量缺失的观测值,尤其是营业收入、固定资产、员工人数和中间投入四类TFP输入变量。
- 连续变量在1%和99%分位做缩尾(winsorize),避免个别极端值主导回归结果。
- 要求公司在样本期内至少连续存在三年,保证面板结构稳定。
需要说明的是,缩尾的时点选择会影响结果。有人先缩尾再计算TFP,有人先算TFP再对回归变量缩尾。我对比下来两边结果差异不大,但论文里一般习惯先缩尾核心投入产出变量,再测算TFP,再对TFP和其他回归变量做第二次缩尾。你复现的时候最好两个口径都跑一下,确认不是缩尾顺序导致结论翻转。
2.4 一个经验:合并前先留好快照
财务数据库更新频率很高,同一家公司同一个年度的数据在不同版本快照里可能不一样,甚至行业代码都会变。为了保证复现结果可追溯,我强烈建议在数据集下载完成后立刻固化一个只读版本,所有清洗和匹配都基于这个版本,不随数据库月度更新而漂移。否则三个月后你想复查一个系数,跑出来的样本量变了,找半天都不知道是哪里的问题。
3. 核心变量:TFP的测度是这篇论文的关键命门
3.1 为什么不能直接用OLS残差当TFP
全要素生产率衡量的是产出中不能被资本和劳动投入解释的部分。最朴素的做法是对生产函数取对数后回归:lnY = βk·lnK + βl·lnL + ε,把残差当成TFP。这个做法看着简单,但存在明显的内生性问题。企业知道自己的生产率水平,高生产率的企业会多投入资本和劳动,也就是说投入变量和残差里的生产率冲击是相关的,OLS估计出来的弹性系数有偏,残差自然也偏了。
工业经济学的文献对此发展出了一套思路:把生产率冲击看成企业决策时能观测到的状态变量,把投入决策内生化,再利用动态面板的矩条件来识别弹性。这就是Olley-Pakes(OP)法和Levinsohn-Petrin(LP)法要做的事。OP用投资作为生产率冲击的代理变量,但很多中国上市公司某些年份投资额为零甚至为负,没法取对数;LP改用中间投入作为代理变量,正好绕开了这个问题。所以论文正文里的TFP一般以LP法为主,OP法和其他方法放进稳健性检验。
3.2 LP法原理:一个两阶段识别故事
LP法假设生产函数是柯布-道格拉斯形式。中间投入的需求函数m_t = m_t(k_t, ω_t)在生产率ω_t上是单调递增的,也就是说企业生产率越高,越愿意买更多中间投入。把这个条件反过来,生产率可以表示成资本和中间投入的函数ω_t = h(k_t, m_t)。这样产出方程就变成:
lnY_t = βl·lnL_t + βk·lnK_t + h(k_t, m_t) + ε_t
第一阶段的思路是把βk和h(k_t, m_t)一起用一个高阶多项式逼近,得到lnY里能被资本和中间投入解释的部分;第二阶段利用生产率冲击的动态性质,比如假设ω_t服从一阶马尔可夫过程,用矩条件 E[ξ_t | k_t, l_{t-1}] = 0 来识别劳动力弹性βl。识别逻辑说白了就是:企业今年的生产率冲击不受去年劳动投入决策的影响,但去年的劳动投入会影响今年的产出,所以劳动弹性可以从跨期矩条件里抖出来。
3.3 LP法实操:命令与手工计算
Stata里的常用工具是prodest命令,我复现时用的基本写法长这样:
* 测算LP法TFP prodest lnY lnL, state(lnK) proxy(lnM) method(lp) reps(50) predict tfp_lp, omega其中lnY取营业收入的对数,lnL用员工人数对数,lnK用固定资产净额对数,lnM用中间投入对数。中间投入的构造口径一般有两种:一种是直接取报表里的“购买商品、接受劳务支付的现金”,另一种是用营业成本加销售费用、管理费用、财务费用之和减去折旧摊销与劳动报酬。不同口径算出的TFP水平不同,但DID回归里的相对变化通常方向一致。论文里一般会交代口径,复现时保持一致就行。
如果要手工复现,思路也很清晰:第一阶段先对lnY、lnL、lnK、lnM做包含三阶交互项的回归,生成φ的拟合值;固定一个候选βk,算出ω(βk) = φ - βk·lnK;然后对ω做三阶多项式回归,取残差ξ;最后用矩条件最小化求解βl和βk。手工实现的好处是能看清每一步在干嘛,坏处是标准误计算麻烦,所以我建议最终呈现结论用包,但理解过程用手工跑一遍。
3.4 TFP测度方法对比
| 方法 | 代理变量 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| OLS残差 | 无 | 简单直观 | 联立性偏差严重 | 仅作参考 |
| 固定效应(FE) | 无 | 控制个体不随时间变化的生产率 | 假设过强 | 稳健性 |
| OP法 | 企业投资 | 处理投资为零的样本 | 投资为负或大量零值时失效 | 投资充分的企业 |
| LP法 | 中间投入 | 中间投入数据更全 | 对代理变量单调性有要求 | 论文基准 |
| ACF法 | 自由设定 | 修正LP/OP的代理变量识别问题 | 操作更复杂 | 基准或稳健 |
需要注意的是,TFP是测出来的潜变量,不是观测值,所以不同方法测出的TFP水平不能直接跨样本比大小。论文能做的,是用不同方法测的TFP做DID回归,看政策效应方向是否一致。只要方向一致、显著性差别不大,结论就算稳住了。
3.5 产出和投入变量的口径选择
产出变量这块有个细节:营业收入里含不含增值税,不同数据库处理不一样,取对数后只影响截距,不影响DID估计量,所以问题不大。真正要紧的是资本投入的口径。固定资产净额受折旧政策影响,不同公司折旧方法不同,会造成测量误差,但面板固定效应能吸收一部分公司层面的系统性偏差。中间投入的构造口径则有讲究:如果中间投入里包含劳动报酬,就会把本来属于劳动的弹性吸收掉,论文的TFP测算会出现系统性偏差。
我当时验算的时候发现,中间投入用“购买商品支付现金”比用“成本费用减折旧减薪酬”算出的劳动弹性更高,这是因为前者更贴近真实的中间品采购流量。复现时建议两种口径都测算,正文用一种,稳健性用另一种,顺便可以验证论文结论是否对口径敏感。
4. 基准DID回归:从公式到表格
4.1 模型设定
论文的核心回归模型可以写成:
lnTFP_it = β·(Treat_i × Post_t) + γ·X_it + μ_i + λ_t + ε_it
其中i是企业,t是年份。Treat_i等于1表示企业注册地位于试点区域,Post_t等于1表示年份在试点启动之后。交互项系数β就是我们最关心的政策效应。X_it是一组随时间变化的企业特征,常见的有企业规模、资产负债率、盈利能力、企业年龄、股权集中度、行业竞争度等。μ_i是企业固定效应,吸收所有不随时间变化的企业特征;λ_t是年份固定效应,吸收宏观经济波动、行业景气度等年度共同冲击。
如果试点区域不是随机划定的,地区层面的时变因素也可能干扰因果识别,比如试点区域恰好赶上了产业结构升级的加速期。为了处理这类问题,很多论文会加入“省份×年份”固定效应,或者在控制变量中加入省级层面变量如地区GDP增速、市场化指数。加不加这层固定效应,是复现中最影响系数的设定之一,强烈建议把几个固定效应组合都跑出来做个对照表。
4.2 固定效应怎么放才踏实
固定效应的组合一般从简到繁:
- 企业固定效应 + 年份固定效应;
- 加入行业×年份固定效应,控制行业层面冲击;
- 再加入省份×年份固定效应,控制地区层面冲击。
难点在于,处理组企业的Treat_i和企业固定效应完全共线,会被吸收掉;Post_t和年份固定效应共线,也会被吸收掉。所以回归里只能放交互项Treat_i×Post_t。如果你在回归里同时放了Treat、Post和交互项,那就说明固定效应没设对,或者用了混合OLS而不是面板设定。
另一个常见的共线问题是行业×年份固定效应加得过细:如果某个行业里的上市公司几乎全部位于试点区域,那么这个行业的行业×年份效应会和政策效应高度共线,交互项系数会变形甚至不显著。遇到这种情况,解决办法是退一步,只加行业固定效应和年份固定效应,或者换粗一点的行业分类。
4.3 标准误聚类到哪一层
微观面板数据里,同一家公司在不同年份的扰动项高度相关,如果不处理,标准误会被严重低估,t值虚高。标准做法是把标准误聚类到企业层面。这是论文的底线设定。
更严格的做法是聚类到省份或城市层面,因为同一个地区的企业共享地区层面的政策冲击,扰动项在地区内部相关。但聚类层级越高,聚类数越少,小样本下推断越不可靠。试点区域的聚类数量只有个位数时,聚类稳健标准误容易产生过度拒绝的问题,一些文献会用wild cluster bootstrap修正。复现时可以同时汇报企业和省份两层聚类结果,如果显著性结论不同,说明结论依赖聚类层级,需要谨慎下判断。
4.4 结果解读:一个系数的经济学含义
TFP取对数后,交互项系数β的经济含义是:试点启动后,试点地区企业的TFP相对非试点地区企业平均多提升(e^β − 1)。如果β等于0.03,说明政策让试点企业TFP额外提升了约3个百分点。
复现时不要只盯着显著性星号,还要看经济显著性。一个年均0.02到0.04的TFP提升,在环保政策评估里是相当可观的效果,因为TFP年增速本身通常也就2%到5%。另外,基准回归系数大小需要和论文对照,如果方向相反或数量级差了十倍,八成是样本筛选或变量构造出了问题,而不是论文错了。
5. 平行趋势、稳健性与机制:给结论加固
5.1 平行趋势检验:事件研究法
DID成立的首要前提是平行趋势假设:政策实施前,处理组和控制组的TFP走势应该没有系统性差异。检验方法是事件研究法,把政策前若干年、政策后若干年分别生成相对年份虚拟变量,再和Treat交互:
lnTFP_it = Σ δ_k·(Treat_i × D_ik) + γX_it + μ_i + λ_t + ε_it
其中k是相对政策年份的距离,以政策前一年为基准组。政策前的交互项系数δ_{−3}、δ_{−2}等应该不显著,政策后的系数应该逐渐变得显著并持续走高。把这个画成图就是很多顶刊里常见的动态效应图。
一个实操细节是,政策相对年份的取值要处理“政策在不同时间启动”的问题。这篇论文涉及的试点在2013年,扩容在2017年,如果样本包含扩容地区,相对年份的计算要以各自进入试点的时间为准,而不是统一用2013年。我复现时为了干净,基准样本就只用首批试点区域,扩容区域剔除。
5.2 安慰剂检验怎么做
平行趋势检验通过不等于没有其他遗漏因素。常用安慰剂检验有两种思路。
第一种是虚构政策时间:把试点启动年份人为提前两年或三年,重新跑DID。如果虚构的政策时点也显著,说明处理组和控制组在没有政策时本来就在分化,真实估计很可能被趋势性差异污染。
第二种是虚构处理组:随机抽取同样数量的公司当假处理组,跑一千次DID,把一千个虚假系数画成分布,真实估计值如果落在分布的极端尾部,说明不太可能纯属运气。这一步我建议直接用固定种子保证可重复,方便日后复查。
5.3 排除同期政策干扰
2013年前后正是多项改革密集落地的时间窗口。如果同一时期还有其他政策只影响了试点地区企业,DID估计就会把这些政策的效应也算到排污权交易头上。常见做法是把潜在的同期政策变量直接加入回归,或者只在样本中剔除那些直接受其他政策影响的行业,再做一遍基准回归。
另一种更稳健的设定是PSM-DID:先在政策前基期用企业特征(规模、资产负债率、盈利能力、行业、区域经济水平)估计处理组企业被选为试点的倾向得分,再为每个处理组企业匹配最相似的控制组企业,用匹配后的样本做DID。PSM-DID的优点是把处理组和控制组在可观测特征分布上拉平,减少线性模型假设的压力;缺点也很现实,倾向得分模型设定不一样,匹配结果就不一样,如果论文作者只报告了一版匹配设定,复现时很难完全对齐。
我个人的经验是把PSM-DID当稳健性检验而不是主结果。如果基准DID和平行趋势检验都稳健,PSM-DID通常只会小幅改变系数;如果PSM-DID结果和基准差很多,要先回头检查有没有“匹配后的样本丢掉了大量处理组企业”这类低级错误。
5.4 机制检验与异质性
论文不只是关心“有没有效应”,还要回答“为什么有效”。机制检验的思路是找到政策影响TFP的中间通道,常见有三条:一是融资约束缓解,排污权配额作为可交易资产,增加了企业的抵押品,同时合规成本压力迫使企业优化资金配置;二是研发投入增加,减排压力带来技术升级需求;三是资源配置优化,企业淘汰低效产能,把资源转向高生产率部门。验证方法一般是对中间变量做同样的DID回归,比如把lnR&D投入换成被解释变量,看政策是否显著提高了研发。
异质性分析同样重要。企业性质(国有/民营)、规模大小、所在行业污染强度、是否出口,都可能是政策效应异质性的来源。分样本回归最大的坑是样本量骤减,交互项系数和标准误都不稳定。更规范的做法是全样本里加入三重交互项,比如Treat×Post×SOE,直接在一个回归里看异质性,同时检验组间系数差异的显著性,而不是简单“一个显著一个不显著就下结论”。
6. 复现中遇到的坑:抢救实录
6.1 常见问题速查表
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
| 回归中Treat项被omitted | 企业固定效应吸收了不随时间变化的变量 | 只保留Treat×Post交互项 |
| 处理组企业数量异常少 | 注册地与经营地混用 | 统一以注册地省份匹配政策区域 |
| 政策前系数显著 | 样本区间太短或政策预期效应 | 提前事件窗口或用公告时间替代实施时间 |
| TFP为负值或极端值 | 生产函数估计出错或中间投入口径错误 | 检查投入变量口径,改用其他TFP方法 |
| 聚类标准误比普通标准误还小 | 聚类层级变量设置错误或聚类数量太少 | 检查聚类变量;小样本用bootstrap |
| 不同固定效应组合下系数翻转 | 行业×年份效应和政策共线 | 简化固定效应组合或更换行业分类 |
| PSM匹配后样本大量减少 | 倾向得分模型支撑不足 | 扩大样本或更换匹配方法 |
6.2 几个高频错误的详解
第一个是政策时点错位。论文里Post的起点是“政策实际启动年份”,而不是“文件下达年份”或“首批交易发生年份”。这三个时点经常差几个月甚至一年多。文件下达后企业会有预期,会提前调整生产决策,所以政策系数可能在正式实施前就开始显著。复现时最好把三个时点都跑一遍,看系数是否对时点选择敏感。如果非要选一个,正文用实施年份,稳健性用公告年份,并把这个差异在注释里交代清楚。
第二个是面板不平衡问题。上市公司会退市、会借壳、会暂停上市,非平衡面板不可避免。如果处理组企业退市率明显高于控制组,DID估计可能受“幸存者偏差”影响。处理办法一是把样本限定在平衡面板做一遍稳健性,二是加入“是否退市”变量观察样本流失是否系统性相关。我实操下来,平衡面板下的系数通常略有变小,方向一致,说明幸存者偏差没有彻底颠覆结论。
第三个是多重共线性被忽视。加入了行业×年份和省份×年份固定效应后,自由度消耗很大,某些细分行业里处理组企业只有个位数,交互项标准误会急剧膨胀。复现时看到t值突然从5掉到1.5,不要急着怀疑变量口径,先检查各固定效应层级的自由度消耗。
第四个是extensive的细节:公司注册地变更。部分上市公司在样本期内变更注册地,如果不处理,同一家公司在政策前后可能被划进不同组别。处理办法有三个选项:按变更前注册地归类、按变更后注册地归类、直接剔除变更企业。论文一般不展开说这个,但复现时你总会撞上,选哪种都要保证报告清楚。
6.3 关于复现这件事本身的一点心得
把整个过程跑完,我对“顶刊复现”这件事最大的体会是:它检验的不是你会不会用一个命令,而是你有没有能力在信息不完整的情况下做出合理选择。论文里很多细节是隐性的,样本区间为什么从某一年开始、为什么排除某类企业、为什么用某种TFP口径,都需要用领域知识去填补。你填得越合理,复现结果就越接近原文;你填得越随意,任何一个看似无关的选择都可能把结论引向相反方向。
具体到数据操作上,我的建议是建一个清晰的目录结构:原始数据、中间数据、脚本、结果、日志分开存放,每次跑完回归把log文件存档。这样哪怕三个月后再回来翻这套代码,也能迅速定位每一步的结果来源。复现的价值不在于还原一个数字,而是当你换数据、换口径、换样本再跑一遍,依然能判断结论是否成立——到了这一步,你就真正掌握了这项研究的方法论。