本文作者:智 淼 中南财经政法大学统计与数学学院
本文编辑:陈梦鹭
技术总编:郭泽源
Stata and Python 数据分析
本文将介绍使用Stata进行数据处理时常用的技巧,包括数据导入时批量设置变量标签、对多个文件进行重复操作以及非平衡面板数据中的缺失值处理。
1. 数据导入-批量设置标签
我们从数据库中下载的数据通常有两个列名,第一行通常是英文列名,第二行是中文列名。在数据处理时,通常会使用英文作为列名,并将中文列名作为其标签。下图为从CSMAR中下载的国内生产总值数据。

通过对所有变量进行循环处理,实现英文变量名作为列名,中文变量名作为标签,具体步骤如下:
import excel using example1.xlsx, clear first //导入数据, 将第一行作为变量名foreach x of varlist * {local vlabel = `x'[1]label var `x' "`vlabel'" //分别给变量加对应的中文标签}drop in 1/2 //删去无用的行
其中local vlabel = `x'[1] 的含义是定义暂元vlabel为各变量的第一个值(即中文列名)。这样就完成了批量设置中文标签。

2.文件重复操作
我们经常需要对一个文件夹内的所有文件进行同样的操作,主要用到的命令是循环语句foreach。
首先,移动至需要进行操作的文件夹路径,fs命令能够列出文件名称(注意:不包括文件夹目录),fs *.dta则列出所有dta文件的名称,并储存在暂元`r(files)'中。
cd 文件路径fs *.dta
返回的文件夹内的dta文件如下:

然后,使用foreach循环语句对每一个dta文件进行循环操作,并对新文件加上后缀"_output"表明是操作后的文件。
foreach f in `r(files)'{use "`f'", clear* do somethingsave `f'_output.dta, replace}
但此处可能出现的一个报错是"invalid name",在下述代码中第四行出现该错误。
foreach f in `r(files)'{use "`f'", clearforvalues i=2005/2021{gen `f'_`i'=sum(year`i') //报错行}save `f'_output.dta, replace}

这是因为Stata要求变量名不能包括A~Z、a~z、0~9与下划线"_"以外的字符,但目标dta文件名称为"xxx.dta",包含不允许的字符"."。因此,我们可以对暂元`f'进行字符串处理,得到不包括".dta"的新暂元`fname'。使用到的命令是substr(),从第一个字符开始截取,一直到第n-4个字符(n为文件名长度):
local fname =substr("`f'", 1, length("`f'")-4)
完整的代码为:
foreach f in `r(files)'{use "`f'", clearlocal fname =substr("`f'", 1, length("`f'")-4)forvalues i=2005/2021{gen `fname'_`i'=sum(year`i')}save `fname'_output.dta, replace}
3.非平衡面板中的缺失值处理
在实证研究中,对缺失值的处理一般有直接删除、插值法补充这两种 。在某些情况下,需要构建平衡面板数据。但某些数据库中会删掉存在缺失的数据行,下载到的数据为非平衡面板数据,这给缺失值的补充增加了难度。因此,我们对数据的处理分为两步:第一,扩充数据为平衡面板数据;第二,使用插值法补充缺失数据。
首先我们查看数据结构:
use example3, cleartab year
发现每一年中的个体数量不同(见列Freq.),说明这是一个非平衡面板数据且有缺失值的个体已经被删除,导致无法直接对缺失值进行线性插值补充。这里使用的数据是2011年至2020年市级金融机构各项贷款余额,数据来自EPS。

命令tsfill能够用填充时间序列数据中的空白和面板数据中的空白,其中选项full仅用于面板数据。tsfill, full将按照面板数据时间变量的最小值和最大值填充每个面板的观测值。注意使用tsfill的前提是已设置时间和个体变量,可以使用tsset(时间序列数据)或xtset(面板数据)命令。
encode city, gen(citycode) //设置城市代码xtset citycode year //设置为面板数据tsfill, full
这样我们就会得到一个"strongly balanced"的面板数据。

但是进一步查看数据,发现tsfill命令仅能补全时间变量和个体变量,而数据集中的其他变量仍是缺失值。

接下来我们需要用到的命令是carryforward,该命令可以简便地通过复制补全所有缺失值。由于该命令只能复制已有数据至缺失值位置,因此只需要对于缺失的字符串型变量进行复制,而无需对待插值的数值型变量进行该处理。选项replace表明对原有的变量进行修改,如果使用 gen(new_var)选项,则生成的新变量new_var是补全后的变量,不修改原变量。
carryforward year city prov citycode, replace

至此,我们已经将数据集扩展为平衡面板数据,并对缺失的字符型变量进行了复制处理。
接下来,使用线性插值法对缺失的数值型变量进行补充。这里用到的命令如下:
by citycode: ipolate ln年末金融机构各项贷款余额 year,gen(插值_ln年末金融机构各项贷款余额) epolate
其中by citycode表明以城市个体分组,对于名为"ln年末金融机构各项贷款余额"的变量进行填补,生成"插值_ln年末金融机构各项贷款余额",epolate则表明对连续年份中间年、首尾年数据缺失的情况进行补全。
通过以上操作实现了非平衡面板到平衡面板数据的转换,并使用线性插值法对缺失的数值型数据进行了填补。
END
重磅福利!为了更好地服务各位同学的研究,爬虫俱乐部将在小鹅通平台上持续提供金融研究所需要的各类指标,包括上市公司十大股东、股价崩盘、投资效率、融资约束、企业避税、分析师跟踪、净资产收益率、资产回报率、国际四大审计、托宾Q值、第一大股东持股比例、账面市值比、沪深A股上市公司研究常用控制变量等一系列深加工数据,基于各交易所信息披露的数据利用Stata在实现数据实时更新的同时还将不断上线更多的数据指标。我们以最前沿的数据处理技术、最好的服务质量、最大的诚意望能助力大家的研究工作!相关数据链接,请大家访问:(https://appbqiqpzi66527.h5.xiaoeknow.com/homepage/10)或扫描二维码:
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
覆水难收!B站弹幕解读舆论情绪
微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。
此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。

