Chapter6——STATA流程语句

Chapter6——STATA流程语句

stata中的循环语句有三类:while循环、forvalues循环、foreach循环

0. 循环语句while

用循环语句编写程序,依次列出 1,2,3,4,5

capture drop count5
program count5
local i=1       //先将宏名为i的宏值设置为1
while `i'<=5{      //判断如果宏值`i'不大于5,就执行{}中的命令,否则跳开
    display `i'    //当执行时显示的宏值`i'
    local i=`i'+1    //重新设定宏名为i的宏值,令其等于`i'+1
}
end
count5     //运行出现结果

代码解释:当`i'最开始设定为1,但是因为1小于5,因此执行{}中的代码。即是显示i的内容。然后循环到6,不再小于等于5,跳出循环{},执行end

但是其实用Python来写的话,会更加好理解

i=1           #local i=1
while i<=5:      #while i<=5:
    print(i)     #display `i'
    i=i+1        #local i=`i'+1
#output:1 2 3 4 5

1. 循环语句forvalues

  • forvalues做循环时,其命令格式
forvalues lname = range {
        Stata commands referring to `lname'
}

/*where range is

#1(#d)#2      meaning #1 to #2 in steps of #d     循环从#1到#2,步长为d 
#1/#2         meaning #1 to #2 in steps of 1      循环从#1到#2,步长为1
#1 #t to #2   meaning #1 to #2 in steps of #t - #1       循环从#1到#2,步长为#t-#1
#1 #t :  #2   meaning #1 to #2 in steps of #t - #1       循环从#1到#2,步长为#t-#1  */
  • 利用forvalues进行循环遍历展示从1到5
forvalues i=1/5{        //1/5是指5个数字:1,2,3,4,5
	display `i'
}
*output:1 2 3 4 5

forvalues i=4(-0.2)0{    //4(-0.2)0指的是初始值为4,步长为-0.2,终值是0的所有数
    display `i'
}
  • forvalues编写程序,计算1+2+3+4+5+……+100的总和
*使用while循环来编写程序
capture program drop sum100
program sum100
local d=1
local s=0
while `d'<=100{
    local s=`s'+`d'
    local d=`d'+1
}
display `s'
end
sum100

*使用forvalues循环来编写程序
scalar s=0
forvalues i=1/100{
    scalar s=s+`i'
}
display s

2. 循环语句foreach

  • foreach做循环时,其命令格式为
foreach lname {in|of listtype} list {
        commands referring to `lname'
}
/*Allowed are
        foreach lname in any_list {
        foreach lname of local    lmacname   {
        foreach lname of global   gmacname   {
        foreach lname of varlist  varlist    {
        foreach lname of newlist  newvarlist {
        foreach lname of numlist  numlist    {                            */
  • (按变量循环)将wage1数据集的变量从nonwhite 到servocc 分别使用tab求频数分布。
use http://fmwww.bc.edu/ec-p/data/wooldridge/wage1, clear
tab nonwhite
tab female    //需要一个个tab来输入
*使用foreach可以通过遍历循环来完成,会方便很多
foreach v of varlist nonwhite-servocc{
    tab `v'
}
  • 将student.dta,economy.dta,math.dta的数据纵向拼接起来
use student,clear
foreach file in economy math{
    append using "`file'"
}
  • (按项循环)逐行显示粮食(rice wheat flax maize)和货币(Dollar Lira Pound RMB)
local grains "rice wheat flax maize"     //先定义所有粮食为一个新的局域暂元
foreach x of local grains{
	display "`x'"
}

global money "dollar lira pound rmb"     //先定义所有的货币为一个新全域的暂元
foreach y of global money{
	display "`y'"
}
  • (生成新变量)生成五个新变量 b1,b2,b3,b4,b5,每个变量都是均匀分布随机数
clear 
set obs 10       //设置10个观察值
foreach v of newlist b1-b5{      //定义b1-b5五个新的变量
	gen `v'=uniform()            //给5个变量的观察值分别赋值均匀分布随机数
}
//注意要区分好观察值obs和变量var的不同
  • (按数值循环)逐行显示 1 2 3 4 8 105
foreach num of numlist 1/4 8 105{
	di `num'
}

3. 嵌套循环

  • 生成 5 个变量,10 个观察值,使得第 i 个变量的第 j 个观察值等于i+j
clear
set obs 10
forvalues i=1/5{      //i赋值为1,2,3,4,5
	gen v`i'=.       //生成一个新的变量v1,v2
	forvalues j=2(2)8{
		replace v`i'=`i'+`j' in `j'
	}
}
l

image-20221021170204775

4. 条件语句

  1. 简单的条件语句

如果是国产车,则价格降 100 元,如果是进口车,则价格提升 200 元

sysuse auto,clear
gen p1=price-100 if foreign==0
replace p1=price+100 if foreign==1
*也可以用一行代码解决以上两行
gen p2=cond(foreign==0,(price-100),(price+100))
  1. 判断奇偶数
  • 采用mod函数来判别奇偶数,mod(x,y) = x - y*floor(x/y),是x/y的余数,若除后的余数为1,则是偶数
capture program drop odd
program odd
args num
if mod(`num',2) != 1{     //若num/2的余数不等于1,则执行
	di"`num' is NOT an odd number"
}
else{
	di"`num' IS an odd number"
}
end
odd 1
  • int()取整,不论后面的小数是什么,只取小数点前的数值
capture program drop odd
program odd
args num 
if int(`num'/2)!=(`num'-1/2){     //若num/2不等于(num-1)/2
	di"`num' is NOT an odd number"
}
else{
	di"`num' IS an odd number"
}
end
odd 1
  1. 检验数据文件中是否有某个变量
capture program drop check
program check
capture program variable `i'
if _rc!=0{
	di "`i not found'"
	exit
}
display "the variable `1' exists." 
end

use hb97,clear
check inc
check exp
  1. 循环语句嵌套条件语句
  • 求 6-500 之间能同时被 2,3,5 整除的数
forvalues x=6/500{         //先把6-500的数循环遍历
    if mod(`x',2)==0 & mod(`x',3)==0 & mod(`x',5)==0{     //在6-500的数中如果是能被2,3,5整除的就执行
        di"the ALL common multiple of 2,3,and 5 id `x'"
    }
}
  • 求 6-500 之间能同时被 2,3,5 整除的最小的数
forvalues x=6/500{
    if mod(`x',2)==0 & mod(`x',3)==0 & mod(`x',5)==0{
        di"the LEAST common multiple of 2,3,and 5 is `x'"
        continue,break
    }
}