应用STATA做统计分析王琦-2016200794-技术经济及管理2016.11.12五、STATA编程基础这一章讨论Stata中一些常用的编程语句。主要讲解do文件与log文件,用户可以将任何顺序的Stata命令存入一个文本文件或do文件中,并通过Stata中的do命令或do文件编辑器来执行。通过使用Stata的do文件,用户可以避免重复键入相同的程序,使得一些重复性编程问题的处理变得更加方便。本章的内容包括do文件和log文件的介绍、局部宏和全局宏、标量和矩阵、循环语句以及如何利用returnlist和ereturnlist命令获得Stata命令的结果,这些内容都是Stata编程的基础。5.1do文件和Log文件5.1.1do文件的编写所谓do文件是以.do为后缀的包含一系列Stata命令的文本文件。编写do文件的标准步骤如下:(1)确定当前工作目录。查看当前工作目录只需输入cd,而要改变当前目录,可以在cd后加上要更改的目标目录地址。(2)打开一个Do文件编辑器。(3)输入Do文件的内容,并保存。保存可以直接点击save按钮,或者打开菜单file,然后寻找并点击save。另外,作为一个比较快捷的方式,用户也可以直接在命令框中输入:doedit5.1do文件和Log文件5.1.2Log文件编写Log文件可以通过log命令创建。例如,为了创建一个名为example.txt的log文件,用户可以在命令框中键入:.logusingexample.txt,textreplace其中replace选项允许新写入的log文件覆盖原有的同名文件。如果这里没有replace,且文件中已经存在同名log文件,Stata会拒绝该文件的创建。当程序执行完毕时,用户可以键入.logclose来关闭当前的log文件。5.2局部宏与全局宏宏在STATA的编程语句中,宏是一个最基本、应用最广泛的要素。一个宏可能包含非常多的变量值。一个宏往往只是一个别名,既包含了它的名字也涵盖了其中的数值。当一个宏的名字无法被使用时,可以通过它的值来调用这个宏。局部宏将在一个do文件或ado文件中创建,并在文件执行完毕后从内存中自动清除,无论程序的结束是自然完成还是突然终止的。全局宏在STATA程序运行的整个过程中都一直存在。5.2局部宏与全局宏5.2.1局部宏【例5-1】请定义一个计数宏count从1到4,定义一个包含四个国家简写(USUKDEFR)的局部宏country,然后通过使用foreach语句(循环语句foreach会在13.4节详细介绍)和display语句生成如下样式的结果:Country1:USCountry2:UKCountry3:DECountry4:FR【例5-2】请定义一个计数宏count从1到4,定义一个包含四个国家简写(USUKDEFR)的局部宏country,然后通过使用foreach语句(循环语句foreach会在)和display语句生成如下样式的结果:1US2UK3DE4FR举例宏的名称宏的内容显示一个宏定义一个局部宏为计数器,初始赋值为0定义一个局部宏country,其赋值为4个字符串表明对country这个局部宏中的每一个元素进行循环表明对于每次循环,重新对局部宏count赋值,在原来的基础上加1表明对每次循环,重新对newlist赋值,其赋值为一个字符串,即newlist原有字符串,加上count的数值再加上country所代表的内容以字符串的形式显示局部宏newlist的内容从这两个例子中可以看出,STATA的宏在创建列表、计算数值、循环索引中都起到了非常重要的作用。宏最常用的还是在do文件与ado文件的编写。宏可以使用户避免重复键入同样的命令或重复输入运行结果。5.2.2全局宏全局宏的内涵与定义方式不同于局部宏。它往往被用来存储整个过程中所需要的用到的宏。例如,当我们需要存储一些当前的数据,且这些数据将会被所有的程序或默认路径下的数据集与do文件所使用时,我们就可以创建一个全局宏。因为全局宏的使用可能会带来一些意想不到的问题,只有在少数下我们才会选择使用全局宏。比如我们在do文件A中创建了一个全局宏abc,之后我们却忘记了。若之后我们在do文件G或H的编写中,又使用了宏abc,此时会将其作为一个它全局宏进行计算,运行出来的结果将会是不合意的,而我们很难避免这样的问题。一些教FORTRAN或C语言的老师经常会鼓励同学们多使用局部宏,尽量避免使用全局宏,运用到Stata的编程中道理也是一样的。5.3一些扩展函数以及列表函数在Stata的编程过程中,用户可以通过许多扩展函数以各种灵活的方式来使用宏,此时需要在宏的名称和扩展函数之间添加一个冒号(:),这样用户便可以更加简单的重获或修改宏的内容。使用宏的扩展函数的语法是:{local|global}macname:extended_function其中,macname是局部宏或者全局宏名,而extended_function就宏的扩展函数。举例【例5-3】请定义一个包含四个国家简写(USUKDEFR)的局部宏country,使用宏扩展函数wordcount定义局部宏wds表示最大的循环个数,使用宏扩展函数word‘i’生成局部宏wd作为计数依据,然后通过使用foreach语句(循环语句foreach会在14.4节详细介绍)和display语句生成如下样式的结果:Country1:USCountry2:UKCountry3:DECountry4:FR利用扩展函数wordcountstring得到country中单词个数循环使用扩展函数word#ofstring,对country中每个单词显示语句“Country‘i'is'wd',其中的序数变量是i,其取值在1到wd之间,步长为15.4标量简介定义标量scalar[define]scalar_name=exp其中,scalar_name是要定义的标量名,标量的赋值通过一个数值或者文字表达式exp来表示。显示标量的内容scalar{dir|list}[_all|scalar_names]其中,scalardir和scalarlist都用于显示标量的内容,其后面可以使用_all表示内存中的所有变量,也可以指定某些标量名称(scalar_names)。从内存中删掉某些标量scalardrop{_all|scalar_names}举例下面举一些简单的例子说明。定义标量a,赋值为2:.scalara=2定义标量b,赋值为a的赋值加上3:.scalarb=a+3定义标量root2,其赋值为2的开方:.scalarroot2=sqrt(2)定义标量s1,其赋值是字符串“helloworld“:.scalars1=helloworld举例显示定义好的所有标量:.scalarlist删掉标量a和b:.scalardropab再比如如下两个命令,要求定义标量,并且将这个标量用于定义新的变量:.scalarroot2=sqrt(2.0)//生成一个标量,其赋值为2的开根号.generateDOublerootGDP=gdp*root2//将这个标量用于定义新的变量5.5循环结构5.5.1forvalues语句forvalues语句如下:forvalueslname=range{commandsreferringto`lname'}其中,lname是指定的局部宏名称,而rang可以有如下形式:#1(#d)#2表示从#1到#2步长为#d#1/#2表示以步长为1从#1到#2举例【例5-4】数据集gdp4cty.dta是美国、英国、德国和法国GDP的季度数据,从1971年的第1季度到1995年的第4季度。(1)这里的任务是利用forvalues语句生成四个变量lngdp1、lngdp2、lndgp3和lngdp4,它们分别是gdp1、gdp2、gdp3和gdp4的对数,然后显示新生成的四个变量的描述性统计量。(2)生成变量gdp1_1995、gdp2_1995、gdp3_1995、gdp4_1995、gdp1_1997、gdp2_1997、gdp3_1997、gdp4_1997、gdp1_1999、gdp2_1999、gdp3_1999、gdp4_1999的描述性统计结果。例5-4序数i取值1到4对每一个i产生一个双浮点变量lngdp'i'取值是log(gdp'i')局部宏i被定义为程序中的一个循环系数,把i的取值范围定义为一个数值列表。序数变量从1995到1999,步长是2序数变量i从1到4对每一个i和y的取值,得到gdp'i'_'y'的描述性统计5.5.2foreach语句foreach语句的语法如下:foreachlname{in|oflisttype}list{commandsreferringto`lname'}可以使用的类型包括:对于每一个局部宏foreachlnameoflocallmacname{对于每一个全局宏foreachlnameofglobalgmacname{对于变量列表中的每一个变量foreachlnameofvarlistvarlist{对于数字列表中的每一个数字foreachlnameofnumlistnumlist{举例【例5-5】这里使用数据集lifeexp来说明foreach命令语句的使用,这个数据集在第三章已经使用过了,该数据集是一个关于全球68国人口生存状况的数据,这些国家分别来自欧亚、北美和南美四大洲。计算这些变量的描述性统计量以及它们与popgrowth的相关性,并且绘制它们与popgrowth的散点图。例5-5对于从lexp到safewater的每一个变量进行操作生产该变量的描述性统计量计算popgrowth与该变量的相关系数绘制popgrowth与该变量的散点图5.6使用Stata命令的结果所有的Stata的命令都可以被归入一下三类:r类、e类、s类(属于这类的情况较少)。其中e类命令是指估计命令(estimationcommands),这类命令将返回两个矩阵:e(b)——被估计的系数矩阵,e(v)——被估计系数的方差与协方差矩阵,同时也会返回一些其他信息(详情参见helpereturn)。其他绝大多数的Stata官方命令属于r类命令,这类命令是将运行结果返回到调用程序当中(详情参见helpreturn)。14.6.1r类命令下面让我们从最简单的r类命令入手。理论上说,所有的Stata命令都会将其所有的输出项存放在一个返回列表中。输入命令:returnlist就可以获得这些输出项。举例【例5-6】打开数据集wage.dta,使用describe命令描述该数据集,然后返回describe命令中的输出项。【例5-7】本例使用数据集abdata.dta,该数据集是一个面板数据,是140个国家1976年到1984年的各种宏观指标。在这里的关键变量是id代表每个国家的标号,year代表年份,一个面板数据通常定义这两个变量以便进行各种面板回归和统计。其他的变量包括就业率emp(%)、平均工资wage(指标)、投资占GDP的百分比cap(%)。要求用tsset命令查看该面板数据的结构,并使用returnlist返回相关的结果。例5-6describre命令的结果观测值个数变量的数量指示变量,一旦数据集被修改,即被制定为1利用summarize中的detail获得返回结果的全部信息观测案例数目均值方差标准差偏度峰度加总最小值最大值5.6.2e类命令通过ereturnlist命令可以返回e类命令的计算结果。ereturnlist命令的语法如下:ereturnlist这个命令在通过Stata执行了e类命令之后使用,大多数的e类命令返回的结果中包含四类:标量——比如e(N),总结估计的过程;宏——比如关于响应变量的信息(e(depvar))、使用的估计方法(e(model));矩阵——系数和方差矩阵(e