开头先给个结论这套城市破产法庭DID数据2016-2025年是拿来做政策效应评估的目标变量一般是企业融资成本、银行信贷配置、企业退出率、债权人回收率这类东西。标题里把“工具变量”单独拎出来意味着这套数据不光是做普通DID还被很多人拿来当IV解决反向因果和遗漏变量问题。整篇文章我会把数据构造逻辑、DID识别原理、工具变量估计流程、Stata实操代码和常见坑一次讲清楚适合正在写实证论文、做课题或者需要复现结果的社科学者和研究生。我实际整理这类数据时最明显的感觉是数据本身不难拿难在把“破产法庭设立”这个制度事件转化成干净、可用、能过审稿人那关的变量。很多同学拿到原始文件就急着跑回归结果连处理组和控制组怎么定义都没想明白最后被质疑识别策略。下面我从头拆一遍。1. 这个数据到底要解决什么问题——拆解标题背后的研究场景1.1 破产审判专业化与DID的天然契合“城市破产法庭”说的是地方政府在部分城市设立专门审理企业破产案件的审判机构。这事最大的特点是时间错开不是所有城市在同一时间点一起动而是分批推进有的城市早在2019年前后就有专门破产法庭有的城市直到2023年甚至2025年才挂牌。这个时间差正是DID双重差分最需要的变异来源。DID的基本逻辑不复杂把城市分成两组已经设立破产法庭的当作处理组一直没设立或设立很晚的当作控制组。比较两组在设立前后某个结果变量的变化差异就能剥离掉时间趋势和其它共同冲击得到破产法庭设立带来的“净效应”。因为制度是城市层面发生的个体企业很难直接影响一个城市是否设立破产法庭所以这个冲击相对外生。2016到2025年这个窗口选得也很讲究。2016年是很多研究起步的基期2025年是能拿到的最近完整区间前后跨越试点前、试点中、推广后多个阶段足够构造事件研究法的动态效应图。如果你只需要短期效应2016到2021就够了想看政策长期效果就得拉满到2025。1.2 为什么还要把它当工具变量用普通DID只能告诉你“设立破产法庭的城市结果变量平均变了多少”。但很多论文的研究问题根本不是“破产法庭是否有效”而是“债权人保护力度如何影响企业融资”或“司法效率如何影响企业进入退出”。这时候破产法庭设立就是一个绝佳的工具变量。举个具体场景你想估计“地区债权人保护水平对企业融资成本的影响”。直接拿债权人保护指数去回归问题很明显——债权人保护好的城市可能经济基本面也好金融生态也好融资成本低不见得是保护水平带来的。债权人保护指数本身可能就是内生的是市场选择的结果。破局思路是用“是否设立破产法庭”这个外生制度冲击当作债权人保护水平变化的工具变量。第一步看破产法庭设立是否显著提升了当地债权人保护水平和破产审判效率第二步用这个外生变异来识别债权保护对企业融资的因果效应。这就是标题里“工具变量”四个字的落点。一句话总结这套数据既能独立做DID论文也能作为IV嵌入到更复杂的研究框架里属于“一鱼两吃”的典型数据产品。2. 数据结构与变量体系设计2.1 城市-年度面板的搭建逻辑拿到这套数据先别急着跑回归第一步是搭建标准的面板结构。常见格式是城市-年度平衡面板单位是地级及以上城市时间范围2016到2025年共10个年度。任何城市在任何年份的观测值都要保留缺了就补0或补缺失值别删行。面板格式是DID的基础后面所有回归都依赖这个二维结构。处理组识别规则要提前定死。我的建议是某城市如果在样本期内正式挂牌了破产法庭就把挂牌当年及以后的所有年份记为1之前记为0即treat×post的标准DID设定。至于挂牌当季还是当月起算建议统一按年度处理因为企业层面结果变量很难匹配到月度。处理组的数量按照公开信息大概在二十个左右不同城市设立时间分布在2019到2023年之间。控制组就是样本期内从未设立破产法庭的其余城市。如果你的样本里包含一些高级人民法院下辖且没有独立破产法庭的城市也可以保留作为控制组只要确认它们确实没设立就行。2.2 核心变量、控制变量与工具变量定义整理变量时要分四个模块缺一个后面都会出问题。核心结果变量覆盖企业融资、信贷和退出市场几个维度我常用的是下面这一套变量类型变量名定义数据来源结果变量loan_rate城市加权平均贷款利率或企业发债利差银保监/债券数据库结果变量credit_size金融机构人民币贷款余额/GDP统计年鉴结果变量baoming_rate企业破产立案数量每万家企业法院文书/公告结果变量recovery_rate破产案件债权回收率公开文书测算处理变量treat城市是否设立破产法庭0/1手工整理时间变量post设立当年及以后1手工整理DID项didtreat×post构造控制变量gdp_growth城市GDP增速统计年鉴控制变量fiscal地方一般公共预算收入/GDP统计年鉴控制变量industry第二产业增加值占比统计年鉴工具变量iv_didtreat×post一阶段核心构造控制变量不是越多越好挑跟企业融资和破产相关的核心城市特征就够。GDP增速控制经济基本面预算收入/GDP控制财政能力产业占控制产业结构。如果你要用工具变量框架注意别把太多内生控制变量塞进去否则二阶段会失去一致性。2.3 数据来源与清洗的常见路径破产法庭设立时间的信息来源主要是法院公告和权威媒体报道整理成城市名单后建议交叉验证两次以上。立案数量和企业破产数据公开渠道能拿到法院公告和裁判文书截面需要自行汇总到城市-年度层面这个环节最容易漏。信贷和宏观数据主要靠各地统计年鉴和统计公报补齐核心是保证城市口径一致有的城市是全市口径有的是市辖区口径混用会直接污染结果变量。清洗时要注意几点一是把城市代码统一带“省直辖县级市”的单独标注别并入普通地级市面板二是缺失值超过三年连续缺失的变量会严重影响估计建议剔除或插补三是确认样本期内是否发生过行政区划调整一旦城市代码变化面板就是断的需要做合并处理。我自己的经验是花两天时间手工核对法院官网的公告信息和地方新闻别偷懒直接拿二手汇总Excel跑。这类制度变量的准确性直接决定DID结果是否可信审稿人对这个问得很细尤其是破产法庭这种有明显时点的事件设立月份误差一个月可能影响全年post值。3. DID识别策略与工具变量估计的原理3.1 DID的双重差分到底在差什么DID的逻辑是用四个组的均值差来干净地识别处理效应。处理组前后相减得到处理组自己的时间变化控制组前后相减得到无处理状态下单纯的时间变化两个差值相减剩下来的就是扣除共同趋势后的处理效应。数学上就是处理组后均值 - 处理组前均值减去控制组后均值 - 控制组前均值。放到回归模型里就是下面这个式子[ Y_{it} \alpha \beta (Treat_i \times Post_t) \gamma X_{it} \mu_i \lambda_t \varepsilon_{it} ]其中Treat是城市分组变量Post是时间分组变量交叉项系数β就是DID估计值也叫处理效应。加上城市固定效应μ_i后城市层面不随时间变化的个体差异都被吸收掉加年份固定效应λ_t后所有城市共同面对的宏观冲击比如利率周期、经济波动也被吸收掉。剩下β识别出来的纯粹是处理组城市在政策冲击后的额外变动。这个模型最核心的假设叫平行趋势假设如果没有设立破产法庭处理组城市的趋势会跟控制组城市一致。这个假设没法直接验证只能通过事件研究法间接检验后面实操部分会说具体怎么做。3.2 工具变量为什么“不可替代”工具变量的核心逻辑套用那句老话找一个影响X但不直接影响Y的变量Z用Z的随机变异来“撬动”X再用被撬动的部分来识别X对Y的因果效应。放到破产法庭的场景里X可能是债权人保护指数或破产审判效率Y是企业融资成本Z就是破产法庭是否设立。为什么破产法庭能当工具变量两个条件缺一不可相关性上设立破产法庭确实会改变当地的破产审判资源配置和执行效率这个没什么争议外生性上影响的是法庭设立时点不是企业融资决策。但排他性必须仔细辩护——破产法庭设立是否可能绕过债权人保护直接影响融资如果有人觉得破产法庭挂牌本身就是给银行和投资者释放信心那就可能通过预期渠道直接影响融资排他性就有瑕疵。处理这个质疑的方式有几种。一是尽量把结果变量限定在非破产相关指标上比如企业实体投资而不是纯债务工具二是控制住其它司法改革变量把可能的混淆路径隔离掉三是用案件量或审判时长作为中间机制变量证明破产法庭确实通过债权保护渠道在起作用。3.3 三阶段识别的完整逻辑链工具变量估计本质上是把原来一步完成的回归拆成两步。第一步用工具变量去解释内生变量得到一个“由外生变异驱动”的内生变量拟合值第二步用这个拟合值替代原来的内生变量跑回归得到一致性估计。这个过程学术上叫两阶段最小二乘即2SLS。放到这个题目里就是第一阶段债权人保护/破产审判效率 f是否设立破产法庭控制变量固定效应第二阶段企业融资成本 g债权人保护/破产审判效率的拟合值控制变量固定效应第二阶段里债权人保护不再是观测到的实际水平而是“由破产法庭设立这个外生冲击解释的那部分水平”。如果系数显著为负说明债权保护提升确实压低了融资成本。还有一层辨识度是破产法庭在不同城市设立的时间窗口不同这个本身就是多期DID。此时可以看作每个城市有自己独立的政策时点staggered DID的框架自动成立。要警惕的是多期DID下传统双向固定效应估计量可能被负权重污染后面常见问题部分会单独给处理建议。4. 实操流程与Stata实现4.1 数据准备与基础变量生成第一步把原始数据整理成面板。假设数据里有city城市代码、year年份、treat是否处理组、post_time该城市法庭设立年份未设立设为空值、y结果变量、x1到x3控制变量。* 生成post变量设立当年及以后为1 gen post 0 replace post 1 if year post_time post_time ! . * 生成DID交互项 gen did treat * post * 面板声明 xtset city year * 生成年份固定效应和城市固定效应 xi i.year i.city这里有个细节容易出错post变量的生成不能直接写成“年份大于等于post_time就为1”因为对于从未设立的城市post_time是缺失值条件判断会返回缺失而不是0。所以必须加上post_time ! .的限制。变量生成完以后先跑一个基础描述性统计重点检查did取值为1的样本量。处理组城市数量乘以处理年数大致能算出有效观测数如果这个数字不合理大概率是post_time录入有误或匹配逻辑有问题。4.2 DID基准回归基准回归用reghdfe跑这个命令比xtreg更快在高维固定效应下也不容易爆内存。reghdfe y did x1 x2 x3, absorb(city year) vce(cluster city) est store baselineabsorb(city year)等价于同时控制城市和年份固定效应vce(cluster city)是把标准误聚类到城市层面允许同一城市不同年份的扰动项相关这是市级DID的标准做法。看结果的时候重点关注did系数。显著为正或者为负取决于你的结果变量方向。比如结果变量是融资成本预期是负号结果变量是破产立案率预期是正号。系数的经济显著性也别忽略除以结果变量均值可以算出相对变化比例这个值超过10%基本就是个有实际影响的效应。如果不想用reghdfextreg版本也完全可以xtreg y did x1 x2 x3 i.year, fe vce(cluster city)两种命令的结果应该一致只是固定效应吸收方式不同。我偏好reghdfe因为它能同时吸收高维固定效应处理大样本时更干净。4.3 平行趋势检验与安慰剂检验平行趋势检验是DID论文的必答题。做法是生成一系列相对时间虚拟变量以政策前一年为基准组看政策之前各期系数是否都不显著。* 生成相对时间 gen rel_time year - post_time * 限制在[-4, 4]范围内去掉重叠 tab rel_time, gen(rel) * 以rel1相对时间-4为基准其余进入回归 reghdfe y rel2 rel3 rel4 rel5 rel6 rel7 rel8 x1 x2 x3, absorb(city year) vce(cluster city)注意rel_time在政策前为正编号、政策后为负编号实际代码要根据自己的设置调整对照组。核心结论是政策发生前的所有相对时间虚拟变量系数都不显著政策后的系数开始显著且方向一致。如果政策前就有显著趋势说明两组本来就不平行DID的识别有效性会受重创。安慰剂检验常用做法是随机安排虚假政策时间或者随机抽取伪处理组重复500到1000次得到虚假估计系数的分布。如果真实估计值落在虚假分布的两端之外说明结果不太可能是纯随机产生的。permute did_coef _b[did], reps(500) seed(123): reghdfe y did x1 x2 x3, absorb(city year) vce(cluster city)这条命令会重复随机重排处理组状态并重新估算did系数最终输出随机系数的分布和真实系数的p值。注意permute的标准误信息不常用主要看系数的随机分布范围。4.4 工具变量2SLS估计完整代码如果按IV框架走第一阶段和第二阶段的回归可以这样写假设内生变量是creditor_protect债权人保护力度工具变量是did。* 第一阶段 reghdfe creditor_protect did x1 x2 x3, absorb(city year) vce(cluster city) est store first_stage * 第一阶段F值 test did * 第二阶段 ivreghdfe y (creditor_protect did) x1 x2 x3, absorb(city year) cluster(city)看第一阶段F值粗略标准是大于10严格点的审稿人会要求大于16.38对应Stock-Yogo检验10%偏误阈值。经验上如果F值低于10还硬跑工具变量偏误带来的问题比OLS可能更严重。第二阶段看的是creditor_protect的系数。这里有个常见错误把did当成IV然后用ivreghdfe处理时第一阶段中did系数不显著说明工具变量对内生变量没有解释力这种时候别继续解读第二阶段结果直接改模型设计。如果你还需要处理内生变量不止一个的情况比如同时把债权人保护和破产审判效率都放进去需要用两个工具变量通常做法是用did和did的滞后项或交互项作为额外工具。这个方案没有统一的模板要根据机制设定来构造。5. 常见问题与排查技巧5.1 多期DID交叠处理的坑传统两向固定效应在多期DID下有一个隐患当处理时点彼此错开时早期处理组会被当成晚期处理组的对照组晚期处理组也会影响早期处理的估计导致估计量存在负权重问题。解决办法有三种按优先级排序。第一是直接用Bacon分解看看各组权重分布是否合理第二是改用Callaway Sant‘Anna2021的基于组的估计量允许每组有自己的动态效应第三是u事件研究回归里用Sun Abraham2021的交互加权估计。后两种在Stata里都有现成命令csdid y x1 x2 x3, ivar(city) time(year) gvar(post_time) method(dripw) estat event eventstudyinteract y x1 x2 x3, vce(cluster city) absorb(city year) event(rel_time) window(-4 4) method(fe)跑完以后对比传统下ivreg和这些稳健估计量如果系数方向和显著性没有根本变化说明结论比较稳如果出现明显分化就要认真对待处理时点选择的内生性。5.2 工具变量无效的典型信号整理数据的时候经常发现第一阶段F值很高但第二阶段的标准误大得离谱系数忽正忽负。这类问题多半不是程序错误而是工具变量刚好是弱识别或者排他性存疑。几个典型信号现象可能原因处理方向一阶段F10工具变量相关性弱换工具或调整样本期二阶段系数异常大弱工具偏误或排他性违逆检查IV和Y的直接关联渠道系数方向跟理论相反处理效应异质性为正负抵消分样本检验或换估计量标准误比OLS大几倍工具变量提取信息有限接受更大的估计不确定性或换IV真心建议跑完2SLS以后至少做一个对比OLS结果的系数符号、显著性和数值大小应该跟2SLS大致方向一致只是数值上2SLS会稍大。如果方向和显著性都反了就得停下来重新审模型设定。5.3 样本与聚类选择的实务建议关于聚类层级市级DID首选聚类到城市层面因为政策冲击发生在城市层面同一城市的样本不应被假定独立。有的论文聚类到城市-年份交互层面这通常更严格但在treat变异本来就来自城市层面时聚类到城市-年份会更容易得到显著的p值审稿人可能会质疑标准误口径。处理组城市只有二十个左右时城市层面聚类会低估标准误因为有效聚类数量太小一般要求四十到五十个才够中心极限定理生效。缓解办法是用wild bootstrap的聚类标准误计算p值boottest did, cluster(city) reps(999)Wild bootstrap能解决少聚类下的推断问题这个方法很多顶刊在复核时会实际执行早做早安心。在代码里注意boottest要基于reghdfe或reg之后的估计结果运行。另一个容易被忽视的点是样本期间的截断问题。2016到2025年这个窗口虽长但部分城市的破产法庭设立时间可能落在2025年底导致post期非常短或根本没有post期。这样的城市建议从处理组剔除或者单独做敏感性分析。同样2025年数据有的城市还没更新完确认数据源下载日期和统计部门发布进度避免某几个城市最后的年度全是缺失。最后分享一个我自己的体会这套数据最大的价值不在跑出来那一个显著结果而在它带来的清晰识别框架。多期DID配合IV老话题也能做出新意但前提是手工整理制度时间时多花点耐心。法院公告、权威报道、地方年鉴三种来源交叉验证比事后找补任何审稿意见都来得有效。工具变量这块宁可第一阶段F值高一点让识别更强也不要为了结果好看塞一堆理论上说不通的工具变量进去。数据会说话但要先把话说清楚。