这篇推文是对本公众号早期推文的思考,漏洞在所难免,欢迎指出。
该文首发于微信公众号
DMETP
,欢迎关注!
在对中国工业企业数据库进行数据清洗之后,一个伴随而来的问题是:数据清洗本身会否影响估计结果?
之所以进行数据清洗,绝不仅仅是为了逼近所谓的“研究范式”,更多在于使得估计结果更能反映“平均水准”,或者确保参与回归的样本的固有特征不存在系统性偏差(这里有点类似于PSM),比如为了排除极端值的干扰,一般都会对连续型变量进行缩尾/截尾处理;比如为了保证所有样本企业的资产负债指标处在一个正常水准,将直接剔除资产负债率大于1或小于0的样本。
数据清洗的本意是为了规避问题,但数据清洗本身可能带来新的不可忽视的问题。
比如,原始数据集中某企业存续期为1998年-2013年,且存续年份不中断(不包括2010年,下同),但是数据清洗之后观察发现该企业样本存续期变为2003-2011年,且2005年-2008年的数据缺省。这样存在的问题是,如果造成数据缺省的原因是异常值,比如在这些缺省年份企业的资产负债率大于1或者小于0,从而导致这些样本在数据清洗时被剔除,那么在参与回归时使用这样的观测值将可能导致样本选择偏误(注意这里不是自选择偏误!)。
为什么会导致样本选择偏误?在数据清洗时,最终决定样本是否参与回归的因素是一个确定的因素,比如上例中的资产负债率,如果资产负债率同时影响回归模型中的核心x
与y
,将造成估计偏误。换句话说,基于一个特定的变量对数据进行清洗,这样的一种选择过程将导致参与回归的样本与被剔除的样本在某些方面存在系统性偏差,即对样本的选择不再随机。
再比如,在将四位数行业分类代码统一至GB2002年版之后,观察发现某企业所属行业在四位数层面发生变动,即同一家企业在不同年份发生了跨行业转移。排除行业分类代码统一错误的可能,使用这样的跨行转移样本来进行估计可能导致样本选择偏误。
为什么会导致样本选择偏误?事实上,数据清洗本身并不是造成自选择偏误根本所在,是样本主体的有意识有方向的决策行为造成了自选择偏误,数据清洗不过是将这一问题暴露出来。比如上文的跨行转移样本,企业基于自身状况与外部环境的研判,自主选择是否进行行业转移。如果这部分企业在行业转移之后产生明显的跨行转移效果,如产值、负债、主营收入等发生突变,并且转移前与行业不变的企业相比差距不大,但转移后差距突变,将造成估计偏误。换句话说,跨行转移企业与未跨行转移企业在某些方面可能存在系统性偏差,即对样本的选择不再随机。特别是,当我们想评估一项政策的政策效果时,并且该项政策以特定行业为实施对象,如果存在以上情况,那么我们就很难判断最终的结果究竟是因为这一项政策带来的,还是企业跨行转移带来的。
以上只是工企数据库进行数据清洗后可能出现的两点比较突出的问题,除此之外还存在单期观测企业、在位企业、持续在位企业与其他企业是否存在系统性差异的问题。解决这些问题的一个常见思路是剔除这些特殊样本进行回归,并将回归结果与基准回归结果进行比较,如果结果差异不大,说明在考虑这些问题之后基准结果依然是稳健可信的(陈登科,2020)。
[1] 陈登科. 贸易壁垒下降与环境污染改善——来自中国企业污染数据的新证据[J]. 经济研究, 2020, 55(12): 98-114.
剔除这部分特殊样本的前提是识别出这些样本,下面的代码是可供参考的识别方案。
*- 单期观测样本
preserve
bys idcode: gen c = _N
duplicates drop idcode, force
tab c
restore // 存续年份分别为1,2,3,...,15年的企业个数
preserve
bys idcode: keep if _N == 1
tab year
restore // 分年度统计单期观测样本数目
*- 跨行业转移样本(四位数行业)
preserve
egen a = nvals(indcode), by(idcode)
gen b = (!1.a)
drop if !1.b
duplicates drop idcode, force
count
restore // 1998-2013年间跨行业转移企业个数
preserve
drop if year >= 2007
egen a = nvals(indcode), by(idcode)
gen b = (!1.a)
drop if !1.b
duplicates drop idcode, force
count
restore // 1998-2007年间跨行业转移企业个数
*- 2007年前后均有观测值(但年份不一定持续)的样本(在位企业)
** 与之相反的是进入退出企业
** 进入企业:2007年以前不存在而2007年或以后存在(但不一定持续存在)的企业
** 退出企业:2007年或以前存在而2007年以后不存在(但不一定持续存在)的企业
preserve
replace year = year - 1 if year > 2010
bys idcode: egen min = min(year)
bys idcode: egen max = max(year)
gen a = (min < 2007 & max > 2007)
count if 1.a
restore
*- 存续年份不中断的样本
** 存续年份不中断,如1998,1999,2000,2001
** 存续年份 中断,如1998,1999, 2001
preserve
replace year = year - 1 if year > 2010
bys idcode: egen min = min(year)
bys idcode: egen max = max(year)
bys idcode: gen N = _N
gen b = (max - min == N)
count if 1.b
restore
*- 存续年份不中断的在位企业样本(持续在位企业)
** 指存续年份不中断且至少包括2007年前后各一期(即2006与2008年)的企业
preserve
replace year = year - 1 if year > 2010
bys idcode: egen min = min(year)
bys idcode: egen max = max(year)
bys idcode: gen N = _N
gen c = (min < 2007 & max > 2007 & max - min == N)
count if 1.c
restore