1.6 常用的几种处理数据的操作
下载资源:\video\第1章\…
下载资源:\sample\第1章\数据1B、数据1C、数据1D、数据1E、数据1F
1.6.1 Stata 16.0的数据类型
在Stata 16.0中,数据类型主要包括3种,分别是数值型数据、字符型数据和日期型数据。
数值型数据由数字、正负号和小数点所组成,包括5个子类,默认类型为float,如表1.5所示。
表1.5 数值型数据
字符型数据由字母、特殊符号和数字所组成,一般会被保存为str#格式,str后面的数字代表最大字符长度,如str8表示可容纳最大长度为8个字符的字符型变量。字符型数据一般用英文状态下的引号""进行标注,且引号一般不被视为字符型变量的一部分。
日期型数据有多种表达方式,例如2019年6月25日,可以写为20190625,也可以写为25062019等。
提示
对于日期型数据,Stata将1960年1月1日视为第0天,该日期之前的天数为负值,比如1959年12月29日为第-3天。
1.6.2 对数据进行长短变换
在对数据进行分析时,可能会遇到需要针对现有的数据进行预处理的情况。在本小节中,我们将通过示例来讲解常用的几种处理数据的操作,包括对数据进行长短变换、类型变换、生成随机数、数据压缩、按变量合并或拆分数据文件、按样本观测值合并或拆分数据文件、添加标签、对数据进行排序等。我们首先讲解对数据进行长短变换,以“数据1B”数据文件为例说明。
在“数据1B”数据文件中,我们设置了4个变量,分别是province、amount2018、amount2019、amount2020。在命令窗口中依次输入以下命令:
reshape long amount,i( province) j(year)(本命令的含义是将数据进行长短变换)
图1.43是将数据进行长短变换的结果。在数据编辑器界面可以看到如图1.44所示的变换后的数据。
图1.43 将数据进行长短变换的结果
图1.44 变换后的数据
reshape wide amount,i( province) j(year)(本命令的含义是将数据变换回来)
图1.45是将数据变换回来,并把表示地区的字符串变量转换成数值数据的结果。在数据编辑器界面可以看到如图1.46所示的变换后的数据。
图1.45 转换成数值数据的结果
图1.46 变换后的数据
1.6.3 对数据进行类型变换
在很多情况下,用户需要对数据进行类型变换,比如字符型变量不能进行数值计算,如果让字符型变量参与数值计算,Stata就会提示错误,此时就有必要将字符型变量转化成数值型变量。用于对数据进行类型变换的常用命令有4个,下面一一说明。
1)encode:从字符串变量转换到数值变量,该命令的语法格式为:
encode varname [if] [in],generate(newvar)[label(name)noextend]
其中generate(newvar) 选项是必须设定的,它作为转换后的新数值型变量的变量名。label(name)用于指定转换后的数值型变量的值标签名,如果未指定label(name)选项,则转换后的数值型变量的值标签名与其变量名相同。只有当label(name)选项指定了新生成变量的值标签,才可以指定noextend选项,如果label(name)选项所指定的值标签中没有varname包含的值,则不会对varname进行编码。默认情况下,label(name)选项的值标签中不存在的值都将添加到该标签中。
2)decode:从数值变量转换到字符串变量,该命令的语法格式为:
decode varname [if] [in],generate(newvar) [maxlength(#)]
其中generate(newvar)选项是必须设定的,它作为转换后的新数值型变量的变量名。maxlength(#)选项用于设定转换后的字符型变量的长度,#的设置值必须在1~32000(字节)。在默认情况下,字符型变量的长度为32000字节。
3)destring:将字符串变量转换为数值变量,该命令的语法格式为:
destring [varlist],{generate(newvarlist)|replace} [destring options]
destring命令将varlist中的变量从字符串转换为数值。varlist是进行数据转化的变量列表,generate(newvarlist) | replace表示生成新的变量或者替换掉原来的变量。options是一些可选项,如果未指定varlist,则destring将尝试将数据集中的所有变量从字符串转换为数值。
4)tostring:将数值变量转换为字符串变量,该命令的语法格式为:
tostring varlist,{generate(newvarlist)|replace} [tostring options]
tostring将varlist中的变量从数值转换为字符串,是使用最紧凑的字符串格式。varlist中已经是字符串的变量将不会被转换。
注意
读者可以看到encode与destring类似,decode和tostring类似,不过它们的差别在于:
1)encode、decode命令是针对varname、newvar的,是变量的概念;而destring、tostring命令是针对varlist、newvarlist的,是变量列表的概念。varlist是一个变量列表。变量列表中的变量要么引用新的(尚未创建的)变量,要么引用现有的变量。一个newvarlist总是专有地引用新的(尚未创建的)变量。类似地,varname指向一个变量,可以是现有的变量,也可以是尚未创建的变量。newvar总是指向一个新变量。
2)encode命令用于给字符型变量重新编码,它只是返回转换后的数值型变量的标签,而不是将原来的以字符型存储的数值变量转换为真正意义上的数值变量。所以,从应用的角度,如果用户只是想为字符型变量贴上1,2,3等表示序号的编码值,将原来的字符型数据设置为转换后的数值型变量的标签,则使用 encode 命令即可;而如果是想在真正意义上将字符型变量转换为数值型变量,则要使用 destring 命令。decode和tostring命令也具有类似的差别。
下面的示例还是基于“数据1B”数据文件,不过在对数据进行长短变换后,在命令窗口中输入以下命令:
encode province,gen(regi) (本命令的含义是把表示地区的字符串变量转换成数值数据的变量)
decode regi,gen(regi1) (本命令的含义是把数值数据的变量转换成表示地区的字符串变量)
结果如图1.47所示。
图1.47 查看数据
然后在命令窗口中输入以下命令:
des(describe命令的简写,该命令旨在生成数据集的摘要)
结果如图1.48所示,可以发现year、amount为数值型。
图1.48 数据摘要
然后在命令窗口中输入以下命令:
tostring year amount, generate(yearnew amountnew)(以生成新的变量yearnew amountnew的方式,将year amount从数值型变量转换为字符型变量)
des(describe命令的简写,该命令旨在生成数据集的摘要)
上述命令的执行结果如图1.49所示,可以发现新生成的变量yearnew amountnew已经变成了字符型。其中yearnew为str4,amountnew为str2,这是因为数据文件中变量year的各样本观测值最长是4位,变量amountnew的各样本观测值最长是2位,然后在命令窗口中输入以下命令:
图1.49 数据摘要
destring yearnew amountnew, generate(yearnew1 amountnew1)(以生成新的变量yearnew1 amountnew1的方式,将yearnew amountnew从字符型变量转换为数值型变量)
des(describe命令的简写,该命令旨在生成数据集的摘要)
上述命令的执行结果如图1.50所示,可以发现新生成的变量yearnew1 amountnew1已经变成了数值型,其中yearnew1为int子类型,amountnew1为byte子类型。
图1.50 数据摘要
注意
在使用destring命令时,需要确保各样本观测值的所有字符均为数字字符。
1.6.4 生成随机数
在命令窗口中依次输入以下命令:
clear (本命令的含义是清除原有数据)
set obs 15 (本命令的含义是设置一个包含15个样本的数据集)
generate suiji=uniform() (本命令的含义是生成一个随机变量,里面包含0~1的15个随机数据)
上述命令的执行结果如图1.51所示。
图1.51 随机数据
然后在命令窗口中输入:
clear (本命令的含义是清除原有数据)
set obs 15 (本命令的含义是设置一个包含15个样本的数据集)
generate suiji=9+9*uniform() (本命令的含义是生成一个随机变量,里面包含[9,18]区间15个随机数据)
上述命令的执行结果如图1.52所示。然后在命令窗口中输入:
clear (本命令的含义是清除原有数据)
set obs 15 (本命令的含义是设置一个包含15个样本的数据集)
generate suiji=9+trunc(9*uniform()) (本命令的含义是生成一个随机变量,里面包含[9,18]区间的15个随机数据,且数据为整数)
上述命令的执行结果如图1.53所示。
图1.52 随机取出15个数据
图1.53 随机取出15个数据且取整
1.6.5 数据压缩
在很多情况下,需要对数据进行压缩,在不改变数据内容和精度的前提下,减少存储空间的占用。数据压缩命令的语法格式为:
compress [varlist]
其中compress为Stata命令,varlist是需要被压缩的变量,如果用户没有指定varlist,那么Stata将对整个数据文件进行压缩。在命令窗口中输入:
clear (本命令的含义是清除原有数据)
set obs 15 (本命令的含义是设置一个包含15个样本的数据集)
gen t=15 (本命令的含义是生成一个名为t的变量,它的值为15)describe (本命令的含义是描述变量的基本情况)
上述命令的执行结果如图1.54所示。可以发现变量t的类型为默认的float。
然后在命令窗口中输入:
compress t (本命令的含义是对变量t进行压缩)
describe (本命令的含义是描述变量的基本情况)
上述命令的执行结果如图1.55所示。可以发现变量t的类型已经被压缩成了占用存储空间较小的byte类型。
图1.54 生成变量t
图1.55 对变量t进行压缩
1.6.6 按变量合并、拆分数据文件
在进行很多数据的处理时,往往需要将两个结构相同或某些部分结构相同的数据文件合并成一个文件,比如两家公司进行了兼并,需要将这两家公司的员工信息表合并为一个信息表,这时就需要对数据文件进行样本观测值的合并;又比如某公司领导想将员工的绩效考核数据和工资薪酬数据放在一起进行数据分析,就需要将员工绩效考核信息表和员工工资薪酬信息表进行合并,这时还需要对数据进行变量的合并。
所以Stata中的数据合并也分为两种:一种是观测值的合并,因为观测值在Stata的数据编辑器视图中是以行来呈现的,因而又被称为纵向合并,也就是将两个有相同变量但具有不同观测值的数据进行合并;另一种是变量的合并,因为变量在Stata的数据编辑器视图中是以列来呈现的,所以又被称为横向合并,也就是将描述同一组观测样本的不同变量合并为一个数据文件,新的数据文件包含所有合并前的各个数据的变量。
本节先介绍按变量合并数据文件,是指将一个外部文件中的若干变量添加到当前工作文件中,即横向合并。按变量合并数据文件,除了“通过观察进行一对一的合并”方式外,增加变量这种合并要求两个数据文件必须具有一个或者多个共同的关键变量,而且这两个文件中的关键变量具有一定数量的相等的观测量数值。所谓关键变量,指的是两个数据文件中变量名、变量类型、变量值排序完全相同的变量。按变量合并数据文件的命令为merge,依据合并方法的不同,有5种命令的语法格式,分别说明如表1.6所示。
表1.6 5种合并方式说明
varlist为进行合并的关键变量。using filename指的是要与源文件合并的文件名及文件路径。默认情况下,merge命令执行后会创建一个新变量_merge,其中包含与合并数据集中的每个观察的源和内容有关的数字代码。[,options]包括很多选项,常用的几个选项说明如下:
1)keepusing(varlist):用来保留合并时using dataset中的部分变量,默认保留全部。
2)generate(newvar):产生一个新的用来标记合并结果的变量,默认是_merge。
3)nogenerate:不创建_merge变量。
4)noreport:不显示匹配结果的汇总表。
5)update:使用被合并数据集中变量的值更新主数据集中同名变量的缺失值,主数据集中的非缺失值不变。
6)replace:使用被合并数据集中变量的非缺失值代替主数据集中同名变量的值,被合并数据集中的缺失值对应的主数据集中的同名变量值不变。此选项要和update一起使用。
7)force:强制字符串/数字变量类型匹配而不会出错。
此处以本书附带的“数据1C”和“数据1D”数据文件为例进行说明,在命令窗口中输入:
use "C:\Users\Administrator\Desktop\数据1C.dta"(本命令的含义是打开“数据1C”数据文件)
merge m:m y1 using "C:\Users\Administrator\Desktop\数据1D.dta"(本命令的含义是将y1作为关键变量,将“数据1D”数据文件中的变量横向合并进“数据1C”数据文件中)
主界面显示的合并结果和数据编辑器界面显示的合并结果分别如图1.56和图1.57所示。操作完成后,可以发现“数据1D”数据文件中的y2、y3被合并进了“数据1C”数据文件中。此外还多了一个名为_merge的变量,这个变量将显示合并的情况,如果数值为3,则合并成功,如果数值为1或2,则合并失败。
图1.56 主界面显示的合并结果
图1.57 数据编辑器界面显示的合并结果
合并之后如何再回到原来的状态,或者如何对数据文件按照变量进行横向拆分呢?前面在1.3节介绍的drop命令和keep命令就可以达到按变量拆分数据文件的目的。
我们可以先将新生成的横向合并后的数据文件复制一份,然后在命令窗口中输入:
drop y2 y3 _merge(本命令的含义是从当前数据文件中删除y2 y3 _merge三个变量)
然后选择菜单“文件|保存”,即可恢复到原来“数据1C”数据文件的状态。
在复制数据文件的命令窗口中输入:
drop y4 y5 y6 _merge(本命令的含义是从当前数据文件中删除y4、y5、y6、_merge四个变量)
然后选择菜单“文件|保存”,即可恢复到原来“数据1D”数据文件的状态。
1.6.7 按样本观测值合并、拆分数据文件
接下来介绍按样本观测值合并数据文件(即纵向合并),将会增加观测量,把一个外部文件中与源文件具有相同变量的观测量增加到当前工作文件中。这种合并要求两个数据文件至少应具有一个属性相同的变量,即使它们的变量名不同。按变量合并数据文件的命令为append,该命令的语法格式如下:
append using filename [filename…] [,options]
using filename指的是要与源文件合并的文件名及文件路径。用户可以用双引号引住文件名,如果文件名中包含空格或其他特殊字符,用户则必须这样做。
此处以本书附带的“数据1E”和“数据1F”数据文件为例进行说明,在命令窗口中输入:
use "C:\Users\Administrator\Desktop\数据1E.dta"(本命令的含义是打开“数据1C”数据文件)
des(describe命令的简写,该命令旨在生成数据集的摘要)
上述命令的执行结果如图1.58所示,可以发现共有样本观测值(obs)30个、变量(vars)6个。
图1.58 纵向合并前的数据集摘要
append using "C:\Users\Administrator\Desktop\数据1F.dta"(本命令的含义是将“数据1F”数据文件纵向合并进当前的“数据1E”数据文件中)
des(describe命令的简写,该命令旨在生成数据集的摘要)
上述命令的执行结果如图1.59所示,可以发现共有样本观测值(obs)67个、变量(vars)6个。“数据1F”数据文件被纵向合并进了当前的“数据1E”数据文件中。
图1.59 纵向合并后的数据集摘要
合并之后如何再回到原来的状态,或者如何对数据文件按照变量进行纵向拆分呢?前面我们在1.3节介绍的drop命令和keep命令就可以达到按变量拆分数据文件的目的。
我们可以先将新生成的纵向合并后的数据文件复制一份,然后在命令窗口中输入:
drop in 31/67(本命令的含义是从当前数据文件中删除第31~67个样本观测值)
然后选择菜单“文件|保存”,即可恢复到原来“数据1E”数据文件的状态。
在复制数据文件的命令窗口中输入:
drop in 1/30(本命令的含义是从当前数据文件中删除第1~30个样本观测值)
然后选择菜单“文件|保存”,即可恢复到原来“数据1F”数据文件的状态。
1.6.8 添加标签
Stata可以为数据库、变量、样本观测值添加标签,添加标签的目的是为了使用户更加清晰地知晓相关数据库、变量、样本观测值的具体含义。
1)为数据库添加标签的命令及其语法格式为:
label data ["label"]
["label"]代表所要添加的标签内容。用户通过该命令在内存中向数据集附加一个标签(最多80个字符)。后续在使用数据集和描述数据集时将显示数据集标签。如果没有指定标签(即未设置["label"],仅输入命令label data),将删除任何现有的标签。
2)为变量添加标签的命令及其语法格式为:
label variable varname ["label"]
varname代表所要添加标签的变量,["label"]代表所要添加的标签内容。用户通过该命令将标签(最多80个字符)附加到指定的变量上。如果没有指定标签(即未设置["label"],仅输入命令label variable varname),则删除任何现有的变量标签。
3)定义值标签的命令及其语法格式为:
label define lblname # "label" [# "label" ...] [,add modify replace nofix]
lblname代表所要定义的数值标签,#代表所要定义的数值,"label"代表所要添加的标签内容。需要用户注意的是后方options的内容,其中add的作用是添加标签内容,modify的作用是对已有的标签内容进行修改,nofix的作用是要求Stata不改变标签的内容而改变原变量的存储容量。lblname最多可以包含65536个独立标签,单个标签最长可达32000个字符。
4)给变量赋值标签的命令及其语法格式为:
label values varlist lblname [,nofix]
varname代表将要添加标签的变量,[lblname]代表刚刚定义的数据标签。
5)列出值标签名及其内容的命令及其语法格式为:
label list [lblname [lblname ...]]
用户通过该命令列出存储在内存中的值标签名及其内容。
6)复制值标签的命令的语法格式为:
label copy lblname [,replace]
用户通过该命令复制一个已存在的值标签。
7)删除值标签的命令的语法格式为:
label drop {lblname [lblname ...] | _all}
用户通过该命令删除一个已存在的值标签。
8)在do-file中保存值标签的命令及其语法格式为:
label save [lblname [lblname...]] using filename [,replace]
用户通过该命令将值标签定义保存在do-file中。这对于没有附加到变量的值标签特别有用,因为这些标签没有随变量保存。
此处以本书附带的“数据1E”数据文件为例进行说明,在命令窗口中输入:
use "C:\Users\Administrator\Desktop\数据1E.dta"(本命令的含义是打开“数据1E”数据文件)
label data "婴幼儿数据"(本命令的含义是为整个数据库添加标签“婴幼儿数据”)
可以看到数据文件已经被加上了标签“婴幼儿数据”,如图1.60所示。
图1.60 数据文件标签
然后在命令窗口中接着输入命令:
label variable label variable y1 "序号"(本命令的含义是为变量y1添加标签“序号”,注意原来该变量就有标签,为“编号”,通过执行该命令,标签变成了“序号”)
可以看到y1变量已经被加上了标签“序号”,如图1.61所示。
label define y2label 1 "male" 2 "female"
label values y2 y2label
其中,y2label表示标签的名称,1 "male" 2 "female"表示定义的规则,数字0的标签是male,数字2的标签是female。
在数据编辑器界面可以看到y2变量的值已经被加上了标签,1为"male",2为"female",如图1.62所示。
图1.61 变量标签
图1.62 值标签
标签添加完以后,可以通过label dir命令查看已经建立标签的相关内容。
1.6.9 对数据进行排序
在很多应用场景,用户需要对数据进行排序处理。Stata排序命令主要为sort命令和gsort命令。
sort命令的语法格式为:
sort varlist [in] [,stable]
varlist代表将要进行排序的变量,[in]代表排序的范围,[,stable]的含义是如果两个观测值相同,其顺序保持与原数据相同。
gsort命令的语法格式为:
gsort [+|-] varname [[+|-] varname ...] [,generate(newvar) mfirst]
其中[+]表示按升序排列,[-]表示按降序排列,Stata默认升序排列。generate(newvar)表示排序之后生成新的变量,mfirst表示将缺失值排在最前面。
此处以本书附带的“数据1E”数据文件为例进行说明,在命令窗口中输入:
use "C:\Users\Administrator\Desktop\数据1E.dta"(本命令的含义是打开“数据1E”数据文件)
sort y5 (本命令的含义是将“数据1E”数据文件中的样本观测值按变量y5从小到大排列)
上述命令的执行结果如图1.63和图1.64所示,其中图1.63为排序前的数据,图1.64为排序后的数据。
图1.63 排序前的y5数据
图1.64 排序后的y5数据
该操作也可以使用gsort命令完成,命令为:
gsort + y5
读者可以自行执行一遍,查看执行结果是否与上述结果相同。