《03SAS函数与CALL子程序.ppt》由会员分享,可在线阅读,更多相关《03SAS函数与CALL子程序.ppt(30页珍藏版)》请在三一办公上搜索。
1、第3章 SAS函数与CALL子程序,清华大学经管学院 朱世武ZResdat样本数据:SAS论坛:,SAS函数定义,SAS函数是一个子程序,对自变量返回一个结果值。SAS函数的形式:函数名(X1,X2,),函数用于组合表达式可以简化编程和统计计算,例3.1 表达式中用函数。data a(keep=date y d min);/*保留date,y,d,min四个变量*/set ResDat.idx000001;y=year(date);/*函数year给出变量date年份*/d=weekday(date);/*函数weekday给出变量date在一周内的哪一天*/min=min(sum(oppr,
2、hipr,lopr,clpr),1000);run;例3.2 条件语句中使用函数。data a;set ResDat.idx000001;where year(date)1996;/*Where语句中使用Year函数*run;,用函数处理多变量可以简化程序,例3.3 用与不用SAS函数时的程序。不用SAS函数。totx=xl+x2+x3+x4+x5+x6+x7+x8+x9+x10;if totxy then least=totx;else least=y;使用SAS函数。leastmin(sum(of x1-x10),y);例中,两段程序的结果相同,第二段只有一个语句,非常简单。,函数自变量,
3、自变量类型:变量名;常数;函数;表达式。例3.4 函数及其自变量类型举例。,自变量个数:有些函数不需要自变量,有些只需要一个自变量,有些函数有多个自变量。SAS9.1中,自变量个数不能超过32767。如果函数的自变量是表达式,在函数被调用之前,所有表达式自变量首先计算。自变量表示法:当函数有多个自变量时,必须用逗号分隔开。自变量名缩写方法:函数名(OF变量名1变量名n),例3.5 正确与错误的表示方法。例3.6 数组元素自变量的缩写方法。array y10 y1-y10;/*定义数组y10*/x=sum(of y*);z=sum(of y1-y10);例中,两个SUM函数的表示法是等价的。,函
4、数结果,通常函数的结果由其自变量的属性决定:自变量是字符时结果变量为字符;自变量是数值时结果变量为数值。PUT函数是一个例外,它不管自变量是什么类型,其结果总是字符值。根据缺省规则,对大多数函数来说,数值目标变量的长度是8,字符目标变量的长度没有缺省规则。目标变量长度不用缺省规则的函数见课本表3.1。,用PUT语句在LOG窗口显示函数值,例3.7 显示概率值和分位数。data;Y=probnorm(1.96);/*标准正态分布小于1.96的概率*/put Y;q1=tinv(.95,2);/*自由度为2的t分布的0.95分位数*/q2=tinv(.95,2,3);/*自由为2,非中心参数为3的
5、t分布的0.95分位数*/put q1=q2=;run;,0.9750021049q1=2.9199855804 q2=13.894376071,日期时间函数,SAS日期和时间存贮标准是以1960年1月1日0时0分0秒为起点,然后以相应的间隔记时。如1960年1月1日9时0分,按日记的数值就是0,按小时记的数值就是9。1960年1月2日0时0分,按日记的数值就是1,按小时记就是24等。由于日期函数是一类非常重要的函数,特别是对金融数据处理和金融计算,借助日期函数可以极大提高效率。,应用举例,例3.8 计算两个日期之间的天数。data _null_;sdate=01jan2002d;edate=
6、01jan2003d;actual=datdif(sdate,edate,act/act);/*按每个月的实际天数算*/days360=datdif(sdate,edate,30/360);/*按每个月30天计算*/put actual=days360=;run;data _null_;actual=datdif(01jan2002d,01jan2003d,act/act);days360=datdif(01jan2002d,01jan2003d,30/360);put actual=days360=;run;例中,两段程序的结果一样。actual=365,days360=360.,例3.10
7、 以日为单位计算当前日期的天数。data;x=date();y=today();put x=y=;run;例中,DATE()和TODAY()结果一样,都是返回当天的天数。当然,也可以用一定的日期格式表示它们。data;x=date();y=today();format x y yymmdd10.;put x=y=;run;,结果显示:x=17232 y=17232,结果显示:x=2007-03-07 y=2007-03-07,例3.12 计算日期值所在的年季月以及处于某月的第几天。data a;set ResDat.stk000001(obs=10);keep date year qtr mo
8、nth day;year=year(date);qtr=qtr(date);month=month(date);day=day(date);proc print noobs;run;,Date year qtr month day1991-01-02 1991 1 1 21991-01-03 1991 1 1 3 1991-01-04 1991 1 1 4 1991-01-05 1991 1 1 5 1991-01-07 1991 1 1 7 1991-01-08 1991 1 1 8 1991-01-09 1991 1 1 9 1991-01-10 1991 1 1 10 1991-01-1
9、1 1991 1 1 11 1991-01-12 1991 1 1 12,例3.14 将日期时间值换算为以秒计数的计算方法。data;mdy=mdy(08,18,2001);put mdy=;format mdy yymmdd10.;hms=hms(21,50,51);put hms=;x=21*60*60+50*60+51;put x=;dhms=dhms(date(),21,50,51);put dhms=;dhms=dhms(15263,21,50,51);put dhms=;y=15263*24*3600+x;put y=;run;,结果显示:mdy=2001-08-18hms=786
10、51x=78651dhms=1347832251dhms=1318801851y=1318801851,概率分布函数,标准正态分布,PROBNORM(X)计算标准正态分布随机变量小于X的概率。例3.15 计算三个特殊的正态概率值。data;P1=probnorm(0);P2=probnorm(1.96);P3=probnorm(2.5758293);put P1=P2=P3=;run;,结果显示:P1=0.5P2=0.9750021049P3=0.9949999999,样本统计函数,样本统计函数在实际中的用处不是很大,因为应用这些函数时,一定要把样本的观测数据放在同一行才可以,现实中样本的观测
11、数据却往往是按一列一列排的。一般情况下,求变量X的样本统计函数值时要用别的方法。样本统计量函数共有15个。,均值,MEAN(of xl-xn)或 MEAN(x,y,z,)计算非缺失自变量的算术平均。自变量中至少有一个非缺失值。,求和,SUM(of xl-xn)或 SUM(x1,x2,)计算自变量的和。要求有两个以上自变量。,方差,VAR(of xl-xn)或 VAR(x1,x2,)计算自变量中非缺失值的方差。要求至少有两个自变量。,随机数函数,SAS系统提供11种随机数函数。由于随机数函数是进行随机模拟的基础,这里我们通过例子,给出每种随机数发生程序,供读者参考。,正态分布,例3.27 用函数
12、RANNOR产生正态分布随机数。data RV;retain _seed_ 0;/*retain 赋初值0给_seed_*/mu=0;sigma=1;do _i_=1 to 1000;Normal1=mu+sigma*rannor(_seed_);/*均值为mu,标准差为sigma*/output;end;drop _seed_ _i_ mu sigma;run;,例3.28 用函数NORMAL产生正态分布随机数。data RV;retain _seed_ 0;mu=0;sigma=1;do _i_=1 to 1000;normal1=0+1*normal(_seed_);/*均值为mu,标准
13、差为sigma*/output;end;drop _seed_ _i_;run;,均匀分布,例3.29 用函数RANUNI产生均匀分布随机数。data RV1;retain _seed_ 0;a=-1;b=2;do _i_=1 to 1000;uniform1=a+(b-a)*ranuni(_seed_);/*区间a,b上的均匀分布*/output;end;drop _seed_ _i_;run;,例3.30 用函数UNIFORM产生均匀分布随机数。data RV1;retain _seed_ 0;a=-1;b=2;do _i_=1 to 1000;uniform1=a+(b-a)*unifo
14、rm(_seed_);/*区间a,b上的均匀分布*/output;end;drop _seed_ _i_;run;,随机数函数自变量SEED,随机数函数使用一个自变量SEED来选择产生随机数的初始种子值,由这个值开始产生随机数流。自变量SEED的取值和初始化类型如下表列出。表3.4 SEED取值与初始化类型,产生随机数的过程中,自变量SEED的值保持不变,种子则不断变化。所以,用随机函数产生随机数时,不能控制种子的值,因此也不可能控制初始化之后的随机数。如果要控制随机数流,就要用随机数函数的CALL子程序。,SAS CALL 子程序,SAS系统提供一系列CALL子程序,用于产生随机数或执行其它
15、的系统功能,详见表3.5,3.6。,随机数子程序,用随机数子程序可以更好地控制种子流和随机数流。除NORMAL和UNIFORM这两个函数之外,所有随机数函数都有一个相应的子程序。CALL语句激活随机数子程序的格式为:CALL routine(seed,variate);选项说明:使用CALL子程序时,首先要对SEED变量赋初值。同时产生几个随机数流时,用CALL子程序比用随机函数的效果更好。因为,用随机数函数同时创建的多个随机数变量都属于同一个随机数流。,例3.38 使用随机函数产生两个随机数变量属于同一个随机数流。data RV;retain seed1 seed2 161321804;do
16、 I=1 to 5;x1=ranuni(seed1);x2=ranuni(seed2);output;end;options nocenter;proc print;run;例中,SEED1和SEED2的初值相同,但X1和X2的第一个观测值却不相同。因为,SEED2的值在这里不起作用,X2的第一个值并不是由SEED2产生的,而是产生第一个X1后一个新种子的结果。所以,这里产生的两个随机数变量属于同一个随机数流。,结果显示:Obs seed1 seed2 I x1 x2 1 161321804 161321804 1 0.43617 0.64888 2 161321804 161321804 2
17、 0.34138 0.42729 3 161321804 161321804 3 0.43237 0.63834 4 161321804 161321804 4 0.74690 0.89710 5 161321804 161321804 5 0.13630 0.19031,例3.39 使用CALL子程序产生两个独立的种子流和随机数流。data RV;retain seed3 seed4 135279821;do I=1 to 5;call ranuni(seed3,X3);call ranuni(seed4,X4);output;end;proc print;run;例中,产生两个独立的种子流
18、和随机数流。因为SEED3=SEED1,所以X3表示的随机数流就是X1和X2组成的随机数流。使用CALL语句时随时可以看到当前的种子值,用随机数函数则看不到。,结果显示:Obs seed3 seed4 I X3 X41 936674311 724196333 1 0.43617 0.337232 1393460745 1733883844 2 0.64888 0.807403 733112270 1200908019 3 0.34138 0.559224 917607517 674688435 4 0.42729 0.314185 928513130 1646762308 5 0.43237 0.76683,