当前位置:文档之家› SAS系统和数据分析用在DATA步的控制语句

SAS系统和数据分析用在DATA步的控制语句

SAS系统和数据分析用在DATA步的控制语句
SAS系统和数据分析用在DATA步的控制语句

第十五课用在DATA步的控制语句

DA TA步的基本概念、流程和有关文件的操作语句我们前面已介绍。但我们所介绍的DA TA步中的SAS语句都是按语句出现的次序对每一个观测进行处理。有时需要对一些确定的观测跳过一些SAS处理语句,或者改变SAS语句的处理次序,就需要用到DA TA步中的控制语句,实现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变量因为没有遇到DA TA语句,继续保持原来值,DO-END循环结束后,DATA步也就结束了。均匀分布随机数是最基本也是最重要的随机数,其他分布的随机数都可以用均匀随机数经过变换得到。最常用的均匀分布随机函数是RANUNI(seed),这个函数是一个模为231-1,乘子为397204094的素数模发生器。Seed必须是小于模231-1任何数值的常数。相同的Seed值会产生相同的随机数序列数,但不同次调用随机函数所产生的值通常是不同的,因此计算机所产生的随机数是一种伪随机数。这个程序中的X1和X2都采用相同种子变量值SEED=20000101所产生的均匀分布的随机数流。SAS系统提供产生了11种常见分布随机数的函数,如表15.1所示,随机数是我们实验和研究问题的重要的输入数据。因此要能编写程序,产生符合要求分布的随机数数据集。

程序运行结果如图15.1所示。

图15.1 用循环DO组产生随机数数据集

表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的整数,00,seed为任意数值RANTBL(seed,p1,…,p2,…pn)产生离散分布随机数,0≤p i≤1,seed为任意数值注:种子seed一般取0,或5位,6位,7位的奇整数。

对于均值为M,标准差为S的正态分布随机数,可由标准正态分布随机数的线性函数得到:

X=M+S*NORMAL(seed)

2.在循环DO组中使用下标数组产生数据集

当我们需要用同一种方法来处理很多变量时,可以用数组语句定义这组变量为数组的一些元素,这个数组中的一些元素就可以在DATA步中较后面的SAS语句里以数组下标的形式被引用。数组ARRAY语句的基本格式为:

Array 数组名{下标} <$><长度> <<数组元素> <(初始值)>>;

例如,以下的几种数组定义方式都是合法的:

●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 个变量,新增变量T i的值与原数据集的变量X j值和新增变量的位置值i有关。为简便起见,假设新增变量T i=∑X j×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所示。

图15.2 循环DO组中使用数组来产生数据集

此程序循环结构是外循环DA TA步执行二次,因此产生二条观测,在每次外循环中,内循环DO重复执行四次,新增四个变量。使用DO语句的循环变量i作为数组的下标,这种下标的使用方法是DO循环中处理下标数组最常用的方法。

3.在循环DO组中使用OUTPUT语句产生数据集

如果在DO-END内循环结束语句END前插入一条OUTPUT语句,那么每次内循环将输出一条观测,而不是内循环所产生的所有变量值只输出在一条观测中。对于每条观测的变量取值,要注意在DATA步的同一个外循环中,已经产生的变量值保持不变,内循环OUTPUT 语句前未赋值的变量为缺失值,直到DA TA步的下一个外循环开始时,所有用INPUT或赋值语句创建的变量在重复DA TA步开始时将被设置为缺失值。我们以上面的程序END语句前插入一条OUTPUT语句为例,程序运行结果如图15.3所示。

图15.3 循环DO组中使用了OUTPUT语句

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。

例如,我们有一组日期DA TE和收盘价CLOSE股票数据,要生成一个带有3日移动平均价MOVEA VER的数据集。所谓3日移动平均价,指最近3日收盘价的平均值,即当天、

昨天和前天收盘价的平均值。昨天和前天收盘价数据要在产生时用RETAIN语句事先保留下来,在计算当日移动平均价时才不至于取到缺失值,而不能计算。为了便于理解,我们将程序编写如下:

Data MA V ;

Retain day 3 i 1 ;

Input date date7. close ;

Array a{4} ;

a{ i }= close ;

Retain ;

If_n_>= day Then do ;

t=0 ;

Do i = 1 to day ;

t= t+a{i};

a{i}= a{i +1} ;

End ;

moveaver=t/day ;

i=day-1 ;

End ;

i=i+1 ;

Card ;

19MAY99 12.41

20MAY99 13.65

21MAY99 15.02

24MAY99 16.52

25MAY99 18.17

Proc print data= MAV ;

Run ;

程序中使用了自动变量_n_,它自动存放当前观测的逻辑顺序号。移动平均价的计算要考虑初始情况,对于3日移动平均价来讲,第一条和第二条观测的3日移动平均价的数值是不存在的,从第三条观测开始有计算数据。程序中的IF语句就是为了判断从第三条观测开始计算3日移动平均价而设置的。第一条RETAIN语句的目的是设置常量day=3,下标变量i的初值为1,第二条RETAIN语句的主要目的是为了保留存放收盘价数据的数组a{i},我们为了使大家明白各个变量的变化过程,RETAIN语句后未专门指定数组a{i},而是保留用INPUT 语句或赋值语句创建的所有变量。如果指定数组a{i},产生的数据集只有DATE、CLOSE和MOVEA VER三个变量。DO-END循环的作用是用T累加器求最近三日收盘价之和,T变量每次求和前要初始化为0。为了始终保持数组a{1} 、a{2}、a{3}中存放的是最近三日的收盘价数据,用a{i}= a{i +1}语句将刚计算过的数据前移,a{2}中数据存放a{1},a{3}中数据存放a{2},a{1}中原数据正常丢弃,留空a{3}准备读下一条记录的收盘价。程序运行结果如图15.4所示。

图15.4 用循环DO组、数组和RETAIN语句所产生的MA V数据集对于只有少量观测的数据集,我们还可以编写如下程序:

Data MA V(Keep= date close moveaver) ;

Retain day 3 ;

Input date date7. close ;

Array a{5} ;

a{ _n _}= close ;

Retain ;

If _n_>= day Then do ;

t=0 ;

Do i =_n _ -day + 1 to _n _ ;

t= t+a{i};

End ;

moveaver=t/day ;

End ;

Card ;

19MAY99 12.41

20MAY99 13.65

21MAY99 15.02

24MAY99 16.52

25MAY99 18.17

Proc print data= MAV ;

Run ;

这个程序的特点是将历史记录的收盘价全部存放到数组a{i}中,因此程序编写简单和短小,容易理解,执行速度快。但它有一个致命的缺点,数组a{i}的大小与记录的条数相关,当实际数据的记录数很大时,将占用很大的存储空间,甚至发生内存溢出错误而不能运行。而前面程序中的数组a{i}大小只与移动平均的天数有关,相对来说是一个很小的数且是固定的数。

当然,以上的程序只是为了说明循环DO组和RETAIN语句的使用,在实际应用中,求移动平均线最简单的方法是采用求滞后值LAGn函数。例如求3日移动平均线相应的程序如下:

Data MA V ;

Input date date7. close ;

Moveaver=(close+lag1(close)+lag2(close))/3;

Card ;

19MAY99 12.41

20MAY99 13.65

21MAY99 15.02

24MAY99 16.52

25MAY99 18.17

Proc print data= MAV ;

Run ;

二、实现选择(SELECT语句)

在DATA步中使用SELECT语句,使SAS系统去执行几条语句或语句组中的一条语句。本质上是一种多路分支结构,当然可以用IF—THEN结构的多层嵌套来实现,但当分支较多时,SELECT语句会很方便,结构也很清楚。SELECT—WHEN结构非常类似其他程序语言中的DO CASE结构。

SELECT语句开始一个SELECT组,SELECT组包括一些WHEN语句,当一个设定的条件为真时,执行对应的WHEN语句给出的一些SAS语句。在SELECT组中至少必须有一个WHEN语句。如果所有的WHEN条件均不成立,那么执行OTHERWISE语句给出的SAS语句。最后用一个END语句结束这个SELECT组。

SELECT语句的一般格式如下:

Select <(select表达式) > ;

When (when表达式) 任意可执行SAS语句;

When (when表达式) 任意可执行SAS语句;

……

Otherwise任意可执行SAS语句;

End ;

如果有SELECT的表达式,首先比较select表达式和第一个when表达式计算结果的大小,相等为真,执行这个WHEN后面的SAS语句;不相等为假,执行下一条WHEN语句或OTHERWISE语句。

如果没有SELECT的表达式,when表达式中一定要含有比较操作符,先求出第一个when 表达式的真假结果,如果为真,执行这个WHEN后面的SAS语句,如果为假,执行下一条WHEN语句或OTHERWISE语句。

要特别注意,一个SELECT组是按顺序判断WHEN语句,一旦某个WHEN语句满足条

件执行了,就跳出这个SELECT组。即使后面WHEN语句也满足条件,也不再执行了。所以,程序员要注意安排好WHEN语句的顺序和条件。

例如,我们有一个CLASS数据集,存放的是学生的成绩表,我们要创建一个新的数据集CLASS02,新增平均成绩A VER变量和等级考评GRADE变量,GRADE的值是根据A VER 值的大小给出A、B、C、D四个等级。

程序如下:

Libname Study “d:\sasdata\mydir” ;

Data

Class02 ;

Set Study.Class ;

aver = (test1+test2+test3)/3 ;

Select ;

When(aver>=90)grade=”A” ;

When(aver>=80) grade=”B” ;

When(aver>=70) grade=”C” ;

Otherwise grade=”D” ;

End ;

Proc print data= Class02 ;

Run ;

程序运行结果见图15.5所示。

三、实现分支(IF语句)

在SAS语言中,IF语句有两种使用格式:

IF语句的格式之一:

图15.5 用SELECT—WHEN组产生的数据集结果

IF 条件表达式THEN SAS语句;

< ELSE SAS语句>;

IF语句的格式之二:

IF 条件表达式;

当我们在创建SAS数据集时使用IF语句的格式之一,可以根据被处理的观测是否使IF 条件表达式为真,来决定是否执行THEN后面的SAS语句。如果条件表达式为假,执行ELSE 后面的语句,没有ELSE语句执行IF语句的下一条语句。

IF—THEN/ELSE语句可以多层嵌套,但要注意IF—THEN/ELSE语句的程序编写格式和匹配。另外,THEN和ELSE后还可以跟DO语句,格式见DO语句的程序格式之一。

1.使用IF—THEN/ELSE语句

例如,我们有一个SURVEY数据集,其中有人的身高HEIGH和体重WEIGHT数据,现在我们要创建一个新的数据集SURVEY02,新的数据集新增一个变量FATNESS,用以标识这个人是否肥胖。假设,人的标准体重计算公式.:男性之标准体重(千克)=身长(厘米)-100,女性之标准体重(千克)=身长(厘米)-102。如果超过标准体重的20%,就算肥胖,用Y来表示,否则用N来表示。

程序如下:

Libname Study “d:\sasdata\mydir” ;

Data Survey02 ;

Set Study.Survey ;

if sex="M" then

if weight>=(heigh*100-100)*1.2then fatness="y";

else fatness="n";

else

If weight>=(heigh*100-102)*1.2then fatness="y";

else fatness="n";

Proc print data= Survey02 ;

Run ;

在使用IF—THEN/ELSE语句的多层嵌套结构时要注意两点:一是要以锯齿型来排列一组组IF—THEN/ELSE语句,目的是为了通过程序书写格式就能明确IF—THEN/ELSE语句的层次和配对。二是如果THEN和ELSE后的SAS语句不直接写在同行的后面,而是写在下一行,THEN和ELSE后不能加分号“;”,表示本程序行并没有结束,直到遇到分号“;”为止。

程序运行结果我们在这里就省略了。

2.使用IF语句

当我们在创建SAS数据集时使用IF语句的格式之二,常用来创建满足IF条件表达式的新数据集。例如,我们要从SURVEY数据集中挑选出所有男性观测来产生一个新数据集SURVEY03。

程序如下:

Libname Study “d:\sasdata\mydir” ;

Data Survey03 ;

Set Study.Survey ;

if sex="M" ;

Proc print data= Survey03 ;

Run ;

四、实现转移(GOTO语句)

GOTO是一种无条件转移语句,它告诉SAS系统立即转到GOTO 语句所指的那条语句,并从那条语句开始执行后面的语句。GOTO语句的实现,是通过GOTO语句中和目标语句前使用相同的语句标号才识别目标和实现转移的。要注意GOTO语句只能在同一个DATA步中进行转移。

GOTO语句的基本使用格式如下:

Data数据集;

……;

GOTO语句标号;

……;

语句标号:……;

……;

Run ;

GOTO语句是一种非结构化程序设计语句,它通过语句标号可转移到任意目的地的特性常常破坏程序的结构化,许多其他语言都不主张使用或禁止使用。当然GOTO语句的功能是可以通过其他结构化控制转移语句替代实现。但是GOTO语句也有明显的特点,能很方便地和灵活地进行转移。

GOTO语句最常见的使用,是出现在IF—THEN语句中,作为THEN分句。例如,我们要对当前输入的一组成绩数据TEST进行动态统计,计数到目前输入为止不及格(<60分)的人数COUNTIF,和累计的总分ACCTEST(包括不及格的分数)。为了使大家明白整个过程,我们创建一个记录过程的数据集CLASS03,且显示出来。

程序如下:

Libname Study “d:\sasdata\mydir” ;

Data Study.Class03 ;

input test @@ ;

retain countif 0acctest 0 ;

If test>=60 then GOTO ok;

countif=countif+1;

ok: acctest=acctest+test ;

cards;

100 90 45 55 80 30

Proc print data= Study.Survey02 ;

Run ;

程序运行结果如图15.6所示。

程序中的ok:acctest=acctest+test累加语句,如果条件不成立,执行完countif=countif+1计数语句后,也要执行此累加语句。如果我们在countif=countif+1计数语句后,ok:acctest=acctest+test累加语句前插入一条RETURN返回语句,RETURN语句的作用是返回到DA TA步的开头处理新的输入数据,相应地程序的作用也发生了变化,不是累加全部的成绩,而是累加及格的成绩,计数器仍然计数不及格的人数。最后的结果是,OBS=6时:COUNTIF=3,ACCTEST=270。

五、实现连接(LINK语句)

LINK连接语句的作用是立即转到由LINK语句指示的语句标号,并从那里开始继续执行语句直到一个RETURN语句被执行。执行RETURN语句立即返回到LINK语句后面的那个语句并从那里继续执行。与GOTO语句一样,LINK语句和语句标号所在的目标语句必须在同一个DATA步中。

LINK语句的基本使用格式如下:

图15.6 用GOTO语句设计的条件计数器和累加器

Data数据集;

……;

LINK语句标号;

……;

……;

RETURN ;

语句标号: ……;

……;

;

Run ;

LINK—RETURN结构从程序执行的本质看,是调用子程序和子程序返回。类似于其他程序语言中转子语句和返回语句。它们都是可以嵌套的,且都用同一RETURN语句返回,返回到调用语句的下一条语句。每一个子程序的RETURN语句能正确地返回调用点,而不发生混乱,是通过内部的堆栈结构实现的。

如果GOTO语句后也有RETURN语句,LINK语句和GOTO语句之间的差别在于这个RETURN语句的作用。LINK后的RETURN让程序返回到LINK后的那条语句;GOTO后的RETURN让程序返回到DATA步的开头。事实上,每一个DATA步的结束处都包含一个隐含的RETURN。因此,没有LINK和RETURN语句的数据步,执行到最后DATA结束处,是通过隐含的RETURN语句返回到数据步DATA开头。有LINK语句而没有RETURN语句的数据步,并不会发生错误,而是执行到最后DA TA结束处,用隐含的RETURN语句返回到LINK后的那条语句。

例如,我们已有一个学生成绩数据集CLASS,原来的成绩分数是按百分数给出的,现在要创建一个新的数据集CLASS04,将百分数成绩改为四级评分:A(100~90)、B(89~80)、C(79~70)、D(<69)。

因为学生成绩数据集CLASS中的成绩数据很多,对每一个百分数成绩数据都要转换为等级分,处理方法都相同,所以我们用调用一个将百分数转换为等级分子程序的方法来实现。子程序中我们用前面已介绍过的SELECT—WHEN选择语句进行转换。

程序如下:

Libname Study “d:\sasdata\mydir” ;

Data Study.Class04(drop= test grade) ;

Set Study.class;

Retain test 0 grade ' ' ;

test=test1 ;link recode ;

grade1=grade ;

test=test2 ;link recode ;

grade2=grade ;

test=test3 ;link recode ;

grade3=grade ;

Return ;

recode:select;

when(test>=90) grade='A';

when(test>=80) grade='B';

when(test>=70) grade='C';

otherwise grade='D';

End ;

Return ;

Proc print data= Study.Class04 ;

Run ;

程序运行结果如图15.7所示。

第十六课每次调用从标号语句recode: select开始到Return语句结束的子程序前,要先给Test变量赋所要转换的分数值。每条观测需要调用三次这个子程序,Test变量的值分别来自数据集字段变量Test1、Test2、Test3。然后子程序根据Test变量的值进行分析判断运算,结果都存放在Grade变量中再返回。因此,每次调用子程序结束后,应该将Grade变量中的结果值运用到某公式中。另外,程序中的第二

图15.7 用LINK语句调用子程序来创建数据集

个Return语句,也就是子程序的返回语句

在本程序中是可以省略的,因为这个Return语句的再下面正好就是DATA步的结束处,它也有一个隐含的Return语句可供子程序返回。用在PROC步中的通用语

当我们用DATA步创建好SAS数据集后,可以用SAS的一些PROC过程步来进一步的分析和处理它们。在DATA步中用户可以使用SAS的语句来编写自己的程序,以便能通过读入、处理和描述数据,创建符合自己特殊要求的SAS数据集。而后由一组组PROC步组成的程序进行后续分析和处理。

一、PROC程序的主要作用

●读出已创建好的SAS数据集

●用数据集中的数据计算统计量

●将统计的结果按一定形式输出

在SAS系统中,计算统计量时,对于许多常用的和标准的统计计算方法,并不需要用户自己编写这些复杂的程序,而是通过过程的名字来调用一个已经为用户编写好的程序。用户通常只要编写调用统计过程前的准备处理程序和输出统计结果后的分析和管理程序。只有用户自己非常特殊的统计计算方法才需要用户自己编写相应的计算程序。

二、PROC过程语句

PROC语句用在PROC步的开始,并通过过程名来规定我们所要使用的SAS过程,对于更进一步的分析,用户还可以在PROC语句中使用一些任选项,或者附加其他语句及它们的任选项(如BY语句)来对PROC步规定用户所需要分析的更多细节。PROC语句的格式为:

PROC 过程名<选项>;

过程名规定用户想使用的SAS过程的名字。例如,我们在前面常使用的打印过程名PRINT,对数值变量计算简单描述统计量的过程名MEANS。

选项规定这个过程的一个或几个选项。不同的过程规定的选项是不同的,因此,只有知道具体的过程才能确定具体的选项是什么。但是,在各个不同过程中使用选项时,下面三种选项的使用格式是共同的:

●Keyword

●Keyword=数值

●Keyword=数据集

Keyword是关键字,第一种选项格式是某个具体过程进一步要求某个关键字;第二种选项格式是某个具体过程要求某个关键字的值,值可能是数值或字符串;第三种选项格式是某个具体过程要求输入或输出数据集。例如:

PROC Print Data=class ;

过程Print,作用为打印输出数据集中的数据。选项为Data=class,关键字是Data,进一步说明要打印输出的数据集名为class。如果省略这个选项,将用最近产生的SAS数据集。

PROC Plot Hpct=50 Vpct=33 ;

过程Plot,作用为描绘变量的散布图。现有两个表示图形大小的选项为Hpct=50 、Vpct=33,关键字Hpct 和Vpct的值分别表示在水平和垂直方向上占一页中的比例。数值50表示占一页的50%,即全页的一半。

PROC Means Data=class Maxdec=3 CSS ;

过程Means,作用为对数值变量计算简单描述统计量。现有三个选项为Data=class 、Maxdec=3 、CSS 。选项Maxdec=3表示该过程输出结果中,小数部分的最大位数为3。选项CSS,是单个关键字,指出MEANS过程选用的计算统计量的方法,在MEANS过程中共有几十种计算统计量方法,CSS表示计算均值偏差的加权平方和。

三、用在PROC步的通用语句

能够出现在PROC步的SAS语句主要分成:

●过程信息语句、

●变量属性语句

●可用在任何地方的全局语句

下面我们列出语句是PROC过程中最常用的一些通用语句,还有很多其他语句对不同的过程是专用的。

1.V AR语句(变量语句)

V AR语句可用在不同的SAS过程中,被用来给出要分析的变量。该语句的格式为:

V AR变量列表;

变量列表给出过程将要分析的数据集中的一些变量。变量列表的任意有效形式都是可以使用的。通常V AR语句是放在过程的开始处。另外,V AR语句中的变量顺序,也是将来输出结果时的变量顺序。

2.MODEL语句(模型语句)

MODEL语句可用在不同的SAS统计过程中,被用来规定分析的模型。尽管MODEL语句的具体语句形式依赖于使用的具体过程,但MODEL语句的一般使用格式为:

MODEL 因变量列表=自变量列表 ;

MODEL语句在使用时,要说明哪些变量是因变量,哪些变量是自变量。另外,不要把“=”号看作是等号或赋值号的作用。例如:

Model y=x1-x5 ;

自变量为x1、x2、x3、x4、x5,因变量为y。

Model y1 y2= a b c d

自变量为a、b、c、d,因变量有两个y1和y2。

3.WEIGHT语句(权数语句)

WEIGHT语句可用在不同的SAS过程中,用来规定一个变量,它的值是这些观测相应的权数。该语句的格式为:

WEIGHT 变量;

WEIGHT语句常常用在这样一些分析中,比如与每个观测有联系的方差不等时,那么可引入一个权数变量,其值和方差的倒数成比例。

4.FREQ语句(频数语句)

FREQ语句可用在不同的SAS过程中,用来规定一个变量,它的值表示这个观测出现的频数。该语句的格式为:

FREQ 变量;

如果在某个观测中,FREQ变量的值小于1,这个观测在分析中不使用;如果FREQ变量的值不是整数,仅取整数部分使用。注意FREQ语句和WEIGHT语句的区别。FREQ变量表示观测出现的次数;WEIGHT变量给出观测相应的权数。当每个观测的权数都是整数时,WEIGHT语句也可用FREQ语句代替。

5.ID语句

ID语句可用在不同的SAS过程中,用来规定一个或几个变量,它们的值在打印输出或这个过程产生的SAS数据集中用来识别观测。该语句的格式为:

ID 变量列表

;

使用了ID语句后,最左边的OBS列被取消了,且ID语句所指定的变量被排列在输出结果报告的最左边。例如,当一个ID语句同PRINT过程一起使用时,输出的观测用ID变量的值来识别,而观测本来的序号没有被打印输出。

6.CLASS语句

CLASS语句可用在不同的SAS过程中,用来指定一些分类变量,SAS过程按分类变量的不同值分别进行分析处理。该语句的格式为:

CLASS 变量列表;

例如,我们要按男女分类统计SURVEY数据集中收入INCOME的平均值。程序如下:

Libname Study "d:\sasdata\mydir" ;

Proc Means Data=Study.Survey ;

Class Sex ;

Var Income ;

Title“How to use CLASS statement”

Run ;

程序运行结果如图16.8所示。

图16.8 在PROC过程中使用CLASS语句分类计算分析SEX

7.BY语句

当用户要求SAS系统对数据集进行分组处理时,可在PROC步中使用BY语句。但处理过程要求数据集事先已经按BY变量排序好了。该语句的一般格式为:

BY 变量1 <…变量2> ;

DESCENDING选项表示它后面的一个变量按降序排列。要特别注意BY后面的变量排列的先后次序,表示分组的的先后次序。例如,有一个关于通讯录的数据集,我们要按居住的城市(City)降序排列,同一城市中按邮编(Zipcode)的升序排列。BY语句的使用格式为:BY DESCENDING City Zipcode

NOTSORTED选项并不是说数据不要求排序,而是要求数据按组整理,并且这些组不必按字母顺序或数值的顺序排序。

但如果要处理的数据集事先没有按BY变量的升序排序,可使用如下几种方法先处理一下数据集:

●在SORT过程中用相同的BY语句对观测进行排序

●用Base SAS软件中DATASETS过程对BY变量生成一个索引

●在PROC调用过程的BY语句中使用NOTSORTED

例如,我们有一个没有按任何变量排序过的SURVEY03数据集,现在要想按男女分组显示观测的NAME和INCOME变量的内容。程序如下:

Libname Study "d:\sasdata\mydir" ;

Proc Sort Data=Study.Survey03 ;

By Sex ;

Proc Print DA TA=Study.Survey03 ;

Proc Print DA TA=Study.Survey03 ;

By Sex ;

Var Name Income ;

Id Sex ;

Run ;

程序运行结果如图16.9所示。

相关主题
文本预览
相关文档 最新文档