SAS系统和数据分析用在DATA步的控制语句
- 格式:doc
- 大小:312.50 KB
- 文档页数:21
第十五课 用在DATA步的控制语句
DATA步的基本概念、流程和有关文件的操作语句我们前面已介绍。但我们所介绍的DATA步中的SAS语句都是按语句出现的次序对每一个观测进行处理。有时需要对一些确定的观测跳过一些SAS处理语句,或者改变SAS语句的处理次序,就需要用到DATA步中的控制语句,实现SAS程序的分支、转移和循环等改变处理次序的功能。
SAS系统提供的控制语句从实现功能的角度看主要有以下五大类:
实现循环(DO语句)
实现选择(SELECT语句)
实现分支(IF语句)
实现转移(GOTO语句)
实现连接(LINK语句)
一、 实现循环(DO语句)
循环程序中使用DO语句的主要形式有四种,如下所示:
DO语句的程序格式之一:
IF条件表达式 THEN DO ;
一些SAS语句 ;
END ;
DO语句的程序格式之二:
DO 变量=开始值 TO 终值 BY 步长值 ;
一些SAS语句 ;
END ;
DO语句的程序格式之三:
DO WHILE (条件表达式 ) ;
一些SAS语句 ;
END ;
DO语句的程序格式之四:
DO UNTIL (条件表达式 ) ;
一些SAS语句 ;
END ;
DO WHILE 和DO UNTIL语句中的表达式是用括号括起来的。两种循环程序格式的区别是,对条件表达式的判断位置。DO WHILE是在循环体的开头,而DO UNTIL是在循环体的结束,也就是说DO UNTIL至少执行循环体中一些SAS语句一次。
下面我们举例来说明DO语句的使用。
1. 使用循环DO组产生随机数数据集
例如,我们需要产生一组均匀分布的随机数流的数据集,程序如下:
Data DoRanuni ;
seed = 20000101 ;
Do I = 1 to 10 by 2 ;
X1=ranuni(seed ) ;
X2=ranuni(seed ) ;
Output ;
End ;
Proc print data=DoRanuni ;
Run ;
程序中的X1和X2都采用相同种子变量值SEED=20000101来产生的均匀分布的随机数流。在数据步DATA中使用DO循环语句时常常与OUTPUT语句配合来产生数据集。OUTPUT语句作用是把当前的观测输出到正在被创建的数据集DoRanuni中。第一次顺序执行产生Seed、I、X1、X2四个变量,OUTPUT输出后,遇到END语句回到DO语句,产生I、X1、X2变量的第二次值,Seed变量因为没有遇到DATA语句,继续保持原来值,DO-END循环结束后,DATA步也就结束了。均匀分布随机数是最基本也是最重要的随机数,其他分布的随机数都可以用均匀随机数经过变换得到。最常用的均匀分布随机函数是RANUNI(seed),这个函数是一个模为231-1,乘子为397204094的素数模发生器。Seed必须是小于模231-1任何数值的常数。相同的Seed值会产生相同的随机数序列数,但不同次调用随机函数所产生的值通常是不同的,因此计算机所产生的随机数是一种伪随机数。这个程序中的X1和X2都采用相同种子变量值SEED=20000101所产生的均匀分布的随机数流。SAS系统提供产生了11种常见分布随机数的函数,如表15.1所示,随机数是我们实验和研究问题的重要的输入数据。因此要能编写程序,产生符合要求分布的随机数数据集。
程序运行结果如图15.1所示。
表15.1 SAS系统的各种随机函数
随机数函数名 作 用
UNIFORM(seed) 产生(0,1)区域均匀分布随机数,乘同余发生器
RANUNI(seed) 产生(0,1)区域均匀分布随机数,素数模发生器
NORMAL(seed) 产生标准正态分布随机数,利用中心极限定理近似公式
RANNOR(seed) 产生标准正态分布随机数,利用变换抽样法
RANEXP(seed) 产生λ=1的指数分布随机数
RANGAM(seed,alpha) 产生伽马分布随机数,alpha>0,seed为任意数值
RANTRI(seed,h) 产生三角分布随机数,0 RANCAU(seed) 产生标准柯西分布随机数 RANBIN(seed,n,p) 产生二项分布随机数,n>0的整数,0 RANPOI(seed,lambda) 产生泊松分布随机数,lambda>0,seed为任意数值 RANTBL(seed,p1,…,p2,…pn) 产生离散分布随机数,0≤pi≤1,seed为任意数值 注:种子seed一般取0,或5位,6位,7位的奇整数。 对于均值为M,标准差为S的正态分布随机数,可由标准正态分布随机数的线性函数得到: X=M+S*NORMAL(seed) 2. 在循环DO组中使用下标数组产生数据集 当我们需要用同一种方法来处理很多变量时,可以用数组语句定义这组变量为数组的一些元素,这个数组中的一些元素就可以在DATA步中较后面的SAS语句里以数组下标的形式被引用。数组ARRAY语句的基本格式为: Array 数组名{下标} <$><长度> <<数组元素> <(初始值)>>; 图15.1 用循环DO组产生随机数数据集 例如,以下的几种数组定义方式都是合法的: Array x{3} T1 T2 T3 ; Array x{5,3} T1-T15 ; Array x{2:6,2:4} T1-T15 ; Array x{3} T1 T2 T3 (100,99,98) ; Array x{*} T1 T2 T3 ; 第一种方式表示定义了一个一维名为X的数组,它有三个元素,对应的变量为T1,T2和T3。第二种方式表示定义了一个二维名为X的数组,它共有5×3=15个元素,对应的变量为T1到T15。第三种方式与第二种方式的区别是还规定每一维下标的下界和上界,通常不特别指明下标的下界从1开始。第四种方式给出了数组中相应元素的初始值T1=100,T2=99,T3=98。第五种方式下标用星号*来代替,表示SAS系统通过数组中的变量个数来确定下标。 下面我们通过一个在循环中使用数组变量来产生一个新的数据集的例子,来说明循环中使用数组变量的用法。假设要由一个老的数据集产生一个新的数据集,新的数据集要新增n个变量,新增变量Ti的值与原数据集的变量Xj值和新增变量的位置值i有关。为简便起见,假设新增变量Ti=∑Xj×i。程序如下: Data DoArray ; Input X1-X3 ; Array a{4} T1-T4 ; Do i = 1 to 4 ; a{i}=(X1+X2+X3)*i ; End ; Card ; 1 2 3 4 5 6 Proc print data= DoArray; Run ; 程序运行结果如图15.2所示。 此程序循环结构是外循环DATA步执行二次,因此产生二条观测,在每次外循环中,内循环DO重复执行四次,新增四个变量。使用DO语句的循环变量i作为数组的下标,这种下标的使用方法是DO循环中处理下标数组最常用的方法。 3. 在循环DO组中使用OUTPUT语句产生数据集 如果在DO-END内循环结束语句END前插入一条OUTPUT语句,那么每次内循环将输出一条观测,而不是内循环所产生的所有变量值只输出在一条观测中。对于每条观测的变量取值,要注意在DATA步的同一个外循环中,已经产生的变量值保持不变,内循环OUTPUT语句前未赋值的变量为缺失值,直到DATA步的下一个外循环开始时,所有用INPUT或赋值语句创建的变量在重复DATA步开始时将被设置为缺失值。我们以上面的程序END语句前插入一条OUTPUT语句为例,程序运行结果如图15.3所示。 图15.2 循环DO组中使用数组来产生数据集 4. 用循环DO组和RETAIN语句产生数据集 由已有数据集产生具有新增变量的新数据集时,通常新增变量值是本条观测原变量值和循环变量值的函数值。但如果新增变量值是历史观测中原变量值和循环变量值的函数值时,首先考虑是将历史观测中原变量值取到中间变量,例如数组变量中。但是因为在每次重复开始DATA步时,所有用INPUT或赋值语句创建的变量将被设置为缺失值,那该如何处理解决呢?在SAS系统中有一条RETAIN语句专门用于解决这一问题。 在数据步DATA中使用了RETAIN语句来为变量设置初值后,RETAIN语句使得用INPUT语句或赋值语句所指定的变量值从DATA步的这次执行到下一次重复时被保留。而如果没有使用RETAIN语句,DATA步每次重复执行之前这些变量就会被设置为缺失值。 我们这里给出了RETAIN语句几种常用的使用格式: Retain ; Retain T1 T2 T3 ; Retain T1 T2 T3 100 ; Retain T1 T2 T3 (100 ) ; Retain T1 T2 T3 (100 99 98 ) ; 第一种使用格式表示用INPUT语句或赋值语句创建的所有变量从DATA步的这次执行到下一次重复时被保留。第二种使用格式规定了变量名字,变量列表或数组名,它们的值是用户想保留的。第三种使用格式表示一个变量列表T1、T2、T3接受同一个初始值100。第四种使用格式是将初始值100用小括号括起来,SAS系统将分配括号中的这个值给变量列表中的第一个变量,即T1=100, T2和T3为缺失值。第五种使用格式给出了初始值列表,将依次分配初始值列表中的值给变量列表中各个变量,即T1=100,T2=99,T3=98。 例如,我们有一组日期DATE和收盘价CLOSE股票数据,要生成一个带有3日移动平均价MOVEAVER的数据集。所谓3日移动平均价,指最近3日收盘价的平均值,即当天、 图15.3 循环DO组中使用了OUTPUT语句