本文作者:余术玲
文字编辑:张馨月
在Stata的编程语句中,宏是一个最基本、应用最广泛的要素。宏是程序中的临时变量,分为名称和内容两部分,类似于变量名和变量值。宏分为局部宏和全局宏,局部宏 local macros 只能在给定的do file或一段交互的程序中使用,全局宏 global macros 在整个Stata的程序中都可以使用,这些最基本的概念想必大家都耳熟能详了,这里就不再赘述了。
今天我们将结合国泰安数据库上面的数据详细介绍高段位玩家是怎么巧用局部宏扩展函数dir,来批量处理文件夹和excel格式的文件。我们从国泰安数据库上面下载了2014年-2018年上市公司的利润表、资产负债表、现金流量表,小编把所使用的数据上传到了爬虫俱乐部云端,存储路径为https://stata-club-1257787903.cos.ap-chengdu.myqcloud.com/CSMAR.rar,读者可自行下载使用。
首先,局部宏扩展函数dir的基本语法为:
local list :dir ["]dirname["] { dirs | files |other}["]pattern["] [, nofail respectcase]
其中,dirname为文件路径名称;dirs| files | other分别代表文件夹、常规文件、非常规文件;pattern为文件或文件夹样式;nofail表示若当前目录下含有太多文件名,则返回适合mname的文件名,而不报错;respectcase表示保留原有文件(夹)名称的大小写形式,否则英文字母默认输出为小写形式。
1.存储文件夹名称
在根目录“D:\财务金融”下有利润表、资产负债表、现金流量表文件夹,如下图:

clear allcd d:\财务金融local dirs: dir "." dirs "*",respectcasedisplay `"`dirs'"'
得到输出结果:

其中,“.”和“*”为通配符;“.”代表缺省路径,“ dir"." ”表示遍历当前路径;“*”可匹配任意零个、单个或多个字符,“ dirs "*" ”表示遍历当前路径下的所有文件夹。
若要存储某一指定路径下的文件夹名称,则将“.”替换为相应的路径名称即可,如下:
clear alllocal dirs :dir "d:\财务金融" dirs "*",respectcasedisplay `"`dirs'"'

2.存储文件名称
在利润表文件夹下面有三个Excel文件,如下图:

我们利用局部宏扩展函数dir将三个文件名称存在指定的局部宏中:
clear allset memory 1000m //设置内存为1000m:\财务金融\利润表
我们依然用“dir "."”表示遍历当前路径,用“files "*.xls"”匹配xls格式的文件,当然如果我们想要匹配其他格式的文件,如dta文件或csv文件,而仅需将扩展名“*.xls”改写为“*.dta”或“*.csv”。
local files: dir "." files "*.xls",respectcasedisplay `"`files'"'

有了以上局部宏扩展函数的基础知识,接下来小编展示如何利用循环批量处理三个文件夹下面的文件,具体程序如下:
clearcd d:\财务金融local dirs: dir "." dirs "*",respectcaseforeach dir in `dirs' {local files: dir "./`dir'" files "*.xls"foreach file in `files' {import excel using ./`dir'/`file',clear firstrow case(lower) //读入到Stata中foreach v of varlist * {quietly replace `v'=ustrregexra(`v',"'|(|)","")} //varlist *表示对所有的变量进行循环,用正则表达式将每个变量值里面的“'”“(”“)”替换成空,因为后面我们要使用nrow命令把第一行观测值变为变量名,这时,包含“'”“(”“)”的观测值会被转换成_var,在此,我们需要提前把“'”“(”“)”全部替换成空,也可以用subinstr函数实现,如/*foreach v of varlist * {replace `v' = subinstr(`v',"'","",.)replace `v' = subinstr(`v',"(","",.)replace `v' = subinstr(`v',")","",.)} */nrow 1drop in 1save ./`dir'/`file'.dta, replace}***我们再把dta格式的文件进行合并并且生成关于年份的变量***clearforeach file in `files' {append using ./`dir'/`file'.dta //此处真的是点睛之笔,再次调用储存文件夹名称的局部宏“`dir'”和储存名称的局部宏“`files'”,实现纵向合并各个文件夹里面所对应的dta格式文件erase ./`dir'/`file'.dta}destring *,replacerename 会计期间 vsplit v,p("-")keep if v2=="12"keep if v3 =="31"drop v v2 v3rename v1 yearorder 证券代码 yeardestring *,replacesave ./`dir'.dta, replace}
处理好的利润表、现金流量表、资产负债表如下图所示:



好了,小编已经将利用局部宏扩展函数dir巧妙处理文件夹和文件这一招传给诸君了,望诸位能够举一反三,灵活运用局部宏扩展函数dir!
自科基金项目信息爬取
rename group批量修改变量名
小命令,大不同——insobs插入新值
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

