本章中,我们将系统学习Stata的语法结构。
Stata的语法范式
Stata所有命令都遵循如下格式要求:
[by varlist:] command [varlist] [using filename] [if exp] [in range] [weight] [, options]
这里有一些格式上的设定是在Stata中通用的,了解这些规则对于大家阅读help文档具有很大的好处。
- 方括号
[]
表示可有可无的内容,
- 斜体内容(例如varlist)表示需要用其他内容代替
- 如果命令名称下有下划线的,代表缩写的最小程度
按照这个规则,显然只有command
(命令名称)是必不可少的,其他的部分都是可有可无。到目前为止,大家已经学习了多条命令,例如cd
, use
, save
, import
等都属于是command。
Stata命令范式中每一部分的功能如下(先有一个大致的印象,后续我们会结合例子具体介绍,在后续的学习过程中也会逐步加强对这部分的理解):
命令名称 Command
命令名称是Stata代码的核心内容,是一条命令中唯一必须要存在的部分。 [by varlist:] command [varlist] [using filename] [if exp] [in range] [weight] [, options]
sysuse auto, clear //打开数据Trd.xlsx,是A股股票的基本信息文件
summarize
sum // 是命令summarize的简写
su // 进一步的简写
s // 出现错误简写的前提是不能引起混淆,无法识别,简写的程度看help文件中命令的下划线
help summarize // 查看syntax部分的 summarize的下划线,确定了最大简写程度
命令可以简写,例如summarize
可以最简写成su
,也就是说写成sum
到summariz
之间的内容都可以被识别。能够精简的最短内容可以通过帮助文件看出,命令名的下划线的内容就是可以最大简写的程度。
变量列表 varlist
[by varlist:] command [varlist] [using filename] [if exp] [in range] [weight] [, options]
varlist
代表多个变量或者一个变量,多个变量之间要用空格隔开。
sysuse auto, clear
summarize //很多命令可以单独使用,单独使用时一般都是针对所有变量进行操作,等同于comamnd _all
summarize _all //与上面的一行命令等价
summarize turn
su turn //
sum turn // 命令缩写
sum tu // 命令缩写的同时,变量名也能缩写
sum t // 这个报错,缩写的前提是能够唯一识别该变量
sort length // 将数据按照变量length取值的升序排序
browse
sort length price // 将数据按照变量length和price取值的升序排序
browse
外部文件 using filename
只在涉及到文件处理的命令中出现。例如append using filename
条件表达式 if exp
条件表达式用于限定命令的作用范围是数据集的全部行还是部分行。
[by varlist:] command [varlist] [using filename] [if exp] [in range] [weight] [, options]
if exp
的作用是对命令的作用范围(哪些observation执行、哪些observation不执行)进行限定,表达式(exp
)的结果为真命题的observation执行命令;当表达式exp
为假命题的observation则不执行命令。
sysuse auto, clear
tabulate rep78
list trunk turn rep78 if rep78 == 2
list if rep78 == 2
browse trunk turn rep78 if rep78 == 5
browse if rep78 == 5
if
语句也可以和_n
、_N
等结合起来,直接依据行数将命令限定与特定的哪些行来执行。 _n
和_N
都是系统保留的字段。其中_N
代表数据中的总行数或者最大行数或者最后一行的行数。_n
代表每一条观测值的行号,取值为1
,2
,…,_N
。
drop if _n == 1 // 删除第1行
drop if _n == 2 //删除第2行
drop if _n >= 1 & _n <= 5 // 删除前5行,符号&表示两个条件同时成立,即逻辑“与”运算
drop if _n >=-5 & _n <= -1 //删除后5行,符号&表示两个条件同时成立,即逻辑“与”运算
drop if _n > (_N – 5) // 删除最后5行
逻辑表达式也可以是一些简单逻辑的复合运算,Stata中逻辑复合运算包括:与、或、非,对应的运算符号是&
、|
和!
。与、或、非的运算逻辑如下(这部分内容我们将会在后续章节中继续学习):
与运算的计算逻辑
A=真 |
B=真 |
A & B = 真 |
A=真 |
B=假 |
A & B = 假 |
A=假 |
B=真 |
A & B = 假 |
A=假 |
B=假 |
A & B = 假 |
或运算的计算逻辑
A=真 |
B=真 |
A | B = 真 |
A=真 |
B=假 |
A | B = 真 |
A=假 |
B=真 |
A | B = 真 |
A=假 |
B=假 |
A | B = 假 |
非运算的计算逻辑
A=真 |
!A = 假 |
A=假 |
!A = 真 |
范围 in
[by varlist:] command [varlist] [using filename] [if exp] [in range] [weight] [, options]
与if和_n, _N连用的效果一样,同样是限定命令的执行在特定行内执行,在其他行内不执行。in后跟着的数字(序列):
- 如果是一个单独的数字,就是对应的行号
- 如果是m/n (其中n>m)的形式,就是从m到n之间的所有整数(每次加1)
- 如果是m(k)n的形式,就是从m开始,每次步长值为k的递增序列。
- m(1)n 与m/n等价
- 负数代表倒数的行数,如-5表示倒数第5行,-1表示倒数第1行(也就是最后一行)
sysuse auto, clear
drop in 1 // 删除第1行
drop in 2 // 删除第2行
drop in 1/5 //删除1到5行,也就是1,2,3,4,5等前5行
drop in 1(1)5 // 不能识别的语法
drop in -5/-1 //删除最后5行,也就是-5,-4,-3,-2,-1等最后5行
分组操作 by
[by varlist:] command [varlist] [using filename] [if exp] [in range] [weight] [, options]
by是Stata命令中的前缀prefix中最为常见的一个,by的作用是将所有的observation按照varlist的取值分组,然后command在每一个分组内分别执行。在使用by对数据分组执行命令之前,必须先对数据进行排序,排序命令是sort varlist,按照varlist中的变量的升序[排序命令我们后续再展开。]依次排序。
sysuse auto, clear
sort foreign
by foreign: summarize price
// 也可以将sort和by合并写成bysort
bysort foreign: summarize price
tabulate rep78, missing
sort rep78
by rep78: summarize price
bysort foreign: summarize price
. sysuse auto, clear
(1978 automobile data)
. sort foreign
. by foreign: summarize price
-------------------------------------------------------------------------------
-> foreign = Domestic
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 52 6072.423 3097.104 3291 15906
-------------------------------------------------------------------------------
-> foreign = Foreign
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 22 6384.682 2621.915 3748 12990
. // 也可以将sort和by合并写成bysort
. bysort foreign: summarize price
-------------------------------------------------------------------------------
-> foreign = Domestic
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 52 6072.423 3097.104 3291 15906
-------------------------------------------------------------------------------
-> foreign = Foreign
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 22 6384.682 2621.915 3748 12990
.
. tabulate rep78, missing
Repair |
record 1978 | Freq. Percent Cum.
------------+-----------------------------------
1 | 2 2.70 2.70
2 | 8 10.81 13.51
3 | 30 40.54 54.05
4 | 18 24.32 78.38
5 | 11 14.86 93.24
. | 5 6.76 100.00
------------+-----------------------------------
Total | 74 100.00
. sort rep78
. by rep78: summarize price
-------------------------------------------------------------------------------
-> rep78 = 1
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 2 4564.5 522.5519 4195 4934
-------------------------------------------------------------------------------
-> rep78 = 2
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 8 5967.625 3579.357 3667 14500
-------------------------------------------------------------------------------
-> rep78 = 3
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 30 6429.233 3525.14 3291 15906
-------------------------------------------------------------------------------
-> rep78 = 4
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 18 6071.5 1709.608 3829 9735
-------------------------------------------------------------------------------
-> rep78 = 5
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 11 5913 2615.763 3748 11995
-------------------------------------------------------------------------------
-> rep78 = .
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 5 6430.4 3804.322 3799 12990
.
. bysort foreign: summarize price
-------------------------------------------------------------------------------
-> foreign = Domestic
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 52 6072.423 3097.104 3291 15906
-------------------------------------------------------------------------------
-> foreign = Foreign
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 22 6384.682 2621.915 3748 12990
.
这里变量foreign
的取值其实并不是Domestic
和 Foreign
,而是0和1,我们看到的是取值标签(value label)。如果通过browse查看的话,其实可以发现变量foreign
的取值是蓝色的,既不是字符的红色、也不是数值的黑色:
tabulate foreign // foreign的取值有两个,"Foreign"和"Domestic",但其实是标签
br if foreign == 1
br if foreign == 0
我们可以使用label
相关的命令查看取值标签:
label dir // 会显示数据中存在名为origin的取值标签
label list origin // 进一步查看origin标签的内容
. label dir // 会显示数据中存在名为origin的取值标签
origin
. label list origin // 进一步查看origin标签的内容
origin:
0 Domestic
1 Foreign
.
另外,需要指出的是,排序sort和分组操作by都是可以针对多个变量进行。
其他选项options
[by varlist:] command [varlist] [if exp] [in range] [weight] [, options]
许多命令中都可以通过option
来丰富命令的执行。例如我们在import excel
命令中通过firstrow
将第一行设定为变量名。再例如,summarize
命令中默认会给出:观测值数量Obs
, 均值Mean
,标准差Std.Dev.
,最小值Min
和最大值Max
。如果我们还想知道中位数,这时候可以在summarize之
后增加, detail
,这会显示更加消息的统计信息。
sysuse auto,clear
sum price
sum price, detail
. sysuse auto,clear
(1978 automobile data)
. sum price
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
price | 74 6165.257 2949.496 3291 15906
. sum price, detail
Price
-------------------------------------------------------------
Percentiles Smallest
1% 3291 3291
5% 3748 3299
10% 3895 3667 Obs 74
25% 4195 3748 Sum of wgt. 74
50% 5006.5 Mean 6165.257
Largest Std. dev. 2949.496
75% 6342 13466
90% 11385 13594 Variance 8699526
95% 13466 14500 Skewness 1.653434
99% 15906 15906 Kurtosis 4.819188
.
加权 weight
[by varlist:] command [varlist] [using filename] [if exp] [in range] [weight] [, options]
加权并不常见,多用于汇总表中的加权计算。例如下标中是一个虚拟的高考成绩分段统计表,是640分及以上成绩一分一段的人数统计,第一列为高考分数,第二列为对应分数的人数。现在我们要计算640分以上全部考生的平均分。
表 3.2 中给出的是汇总后的分数,即每一个分数上的人数。
在之前的课程中,我们介绍过命令summarize varname
可以给出变量的描述性统计,其中就包括均值。但是如果直接用命令summarize分数得到的平均分不能反映出真实的均值。如果要计算这些学生的平均成绩,应该用每个分数上所有人的成绩加总再除以所有的人数。即:
6650\times 193/\sum(193,\cdots, 38)+\cdots+640/\sum(193,\cdots, 38)
这个公式可以 理解成score变量按照num变量的加权平均值,权重是每个分数上人数占全部人数的比例。可以使用summarize结合加权的方式,用一条命令来实现计算均值:
clear
input score num
650 193
649 26
648 23
647 16
646 21
645 26
644 32
643 23
642 38
641 29
640 38
end
summarize score
summarize score [weight=num]
. clear
. input score num
score num
1. 650 193
2. 649 26
3. 648 23
4. 647 16
5. 646 21
6. 645 26
7. 644 32
8. 643 23
9. 642 38
10. 641 29
11. 640 38
12. end
. summarize score
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
score | 11 645 3.316625 640 650
. summarize score [weight=num]
(analytic weights assumed)
Variable | Obs Weight Mean Std. dev. Min Max
-------------+-----------------------------------------------------------------
score | 11 465 646.4903 3.884966 640 650
.
习题
- 梳理到目前为止学过的命令,结合其帮助文档,熟悉命令的语法结构。
本章附录
本章代码汇总
// command
sysuse auto, clear
summarize
sum // 是命令summarize的简写
su // 进一步的简写
s // 出现错误简写的前提是不能引起混淆,无法识别,简写的程度看help文件中命令的下划线
help summarize // 查看syntax部分的 summarize的下划线,确定了最大简写程度
// varlist
summarize //很多命令可以单独使用,单独使用时一般都是针对所有变量进行操作,等同于comamnd _all
summarize _all //与上面的一行命令等价
summarize turn
su turn //
sum turn // 命令缩写
sum tu // 命令缩写的同时,变量名也能缩写
sum t // 这个报错,缩写的前提是能够唯一识别该变量
sort length // 将数据按照变量length取值的升序排序
browse
sort length price // 将数据按照变量length和price取值的升序排序
browse
// if exp
sysuse auto, clear
tabulate rep78
list trunk turn rep78 if rep78 == 2
list if rep78 == 2
browse trunk turn rep78 if rep78 == 5
browse if rep78 == 5
sysuse auto, clear
drop if _n == 1 // 删除第1行
drop if _n == 2 //删除第2行
drop if _n >= 1 & _n <= 5 // 删除前5行,符号&表示两个条件同时成立,即逻辑“与”运算
drop if _n >=-5 & _n <= -1 //删除后5行,符号&表示两个条件同时成立,即逻辑“与”运算
drop if _n > (_N – 5) // 删除最后5行
// in range
sysuse auto, clear
drop in 1 // 删除第1行
drop in 2 // 删除第2行
drop in 1/5 //删除1到5行,也就是1,2,3,4,5等前5行
drop in 1(1)5 // 不能识别的语法
drop in -5/-1 //删除最后5行,也就是-5,-4,-3,-2,-1等最后5行
// by varlist
sysuse auto, clear
sort foreign
by foreign: summarize price
// 也可以将sort和by合并写成bysort
bysort foreign: summarize price
tabulate foreign // foreign的取值有两个,"Foreign"和"Domestic",但其实是标签
br if foreign == 1
br if foreign == 0
label dir
label list origin
// weigth
clear
input score num
650 193
649 26
648 23
647 16
646 21
645 26
644 32
643 23
642 38
641 29
640 38
summarize score
summarize score [weight=num]