本章主要内容
- SAS函数定义
- SAS函数自变量与结果
- SAS函数分类
- 日期时间函数
- 常用概率分布函数
- 样本统计函数
- 随机数函数
- SAS Call子程序
3.1 SAS函数定义
3.1.1 函数定义
SAS函数是一个子程序,对自变量返回一个结果值。
SAS函数形式:
函数名(X1,X2,...)
3.1.2 函数用法
1.用于组合表达式和条件语句
函数用于组合表达式可以简化DATA步编程和一些统计计算
例3.1 表达式中用函数
471 libname ResDat 'F:\ResDat\ResDat';
NOTE: 已成功分配逻辑库引用名“RESDAT”,如下所示:
引擎: V9
物理名: F:\ResDat\ResDat
472 data a(keep=date y d min); /*数据集A只保留date,y,d,min 4个变量*/
473 set ResDat.idx000001; /*函数weekday给出变量date在一周内的哪一天*/
474 y=year(date);
475 d=weekday(date);
476 min=min(sum(oppr,hipr,lopr,clpr),1000);
477 run;
NOTE: 从数据集 RESDAT.IDX000001. 读取了 3891 个观测
NOTE: 数据集 WORK.A 有 3891 个观测和 4 个变量。
NOTE: 压缩的数据集 WORK.A 增大了 50.00%。
压缩为 3 页;不压缩将需要 2 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.01 秒
CPU 时间 0.03 秒
任何使用SAS表达式的地方都可以使用SAS函数,这样可以简化条件语句。
例3 用SAS函数处理变量可以简化程序
487 data a;
488 set ResDat.idx000001;
489 where year(date)>1996; /*Where语句中使用Year函数*/
490 run;
NOTE: 从数据集 RESDAT.IDX000001. 读取了 2365 个观测
WHERE YEAR(date)>1996;
NOTE: 数据集 WORK.A 有 2365 个观测和 20 个变量。
NOTE: 压缩的数据集 WORK.A 大小减少了 0.00%。
压缩为 6 页;不压缩将会要求 6 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.02 秒
CPU 时间 0.01 秒
2.用于处理多变量
例3.3 用SAS函数处理多变量可以简化程序
不用SAS函数
totx=x1+x2+x3+x4+x5+x6+x7+x8+x9+x10;
if totx<y then least=totx;
else least=y;
使用SAS函数
least=min(sum(of x1-x10),y)
3.2 SAS函数自变量与结果
3.2.1 函数自变量
1.自变量类型
- 变量名
- 常数
- 函数
- 表达式
2. 自变量个数
有些函数不需要自变量,有些只需要一个自变量,有些函数有多个自变量。
3.自变量表示法
当函数有多个自变量时候,必须用逗号隔开。
4.自变量名缩写方法
- 函数名(OF变量名 1- 变量名 n);
- 函数名(OF变量名1 ... 变量名n)。
例3.5 正确与错误的表示方法
正确的表示方法 错误的表示方法
sum (x,y,z) sum (x y z)
sum (of x1-x10) sum(x1-x10)
sum (of x1-x10 d y1-y100) sum(x1-x10 d y1-y100)
例 3.6 数组元素自变量的缩写方法
array y{10} y1-y10 /*定义数组y{10}*/
x=sum (of y{ * }); /*y{ * }中的*是显式下标数组的特殊表示符号/
z=sum (of y1-y10)
3.2.2 函数结果
函数的结果由其自变量的属性决定:
- 自变量是字符时结果变量为字符;
- 自变量是数值时结果变量为数值;
PUT函数是一个例外,不管是自变量是什么类型,其结果总是字符值。根据默认规则,对大多数函数来说,数值目标变量长度都是8 ,目标变量的长度不用默认规则的函数,又下表给出:
表:目标变量长度不用默认规则的函数
函数 目标变量类型 目标变量长度
INPUT 数值或字符 函数自身规定的输入格式的宽度
PUT 字符 函数自身规定的输出格式的宽度
SUBSTR 字符 自变量的长度
TRIM 字符 自变量的长度
3.2.3 显示函数的简单方法
SAS系统显示函数值的简单方法是用PUT语句在LOG窗口显示的:
例:
498 data;
499 Y=probnorm(1.96); /*标准正态分布小于1.96的概率*/
500 put Y;
501 q1=tinv(.95,2); /*自由度为2的t分布的0.95分位数*/
502 q2=tinv(.95,2,3); /*自由度为2,非中心参数为3的t分布的0.95分位数*/
503 put q1= q2=;
504 run;
0.9750021049
q1=2.9199855804 q2=13.894376071
NOTE: 数据集 WORK.DATA10 有 1 个观测和 3 个变量。
NOTE: 压缩的数据集 WORK.DATA10 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.04 秒
CPU 时间 0.03 秒
3.3 SAS函数分类
在SAS系统下的帮助菜单下选择SAS FUNCTIONS :Function Categories 就可以得到下表所示的函数:
3.4 日期时间函数
3.4.1 日期时间函数
日期函数是一类非常重要的函数。特别是对金融数据处理和金融计算。
3.4.2 应用举例
例3.8 计算两个日期之间的天数
424 data _null_;
425 sdata='01jan2002'd;
426 edata='01jan2003'd;
427 actual=datdif(sdata,edata,'act/act');
428 days360=datdif(sdata,edata,'30/360');
429 put actual= days360=;
430 run;
actual=365 days360=360
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.00 秒
CPU 时间 0.00 秒
405 data _null_; 406 actual=datdif('01jan2002'd,'01jan2003'd,'act/act'); 407 days360=datdif('01jan2002'd,'01jan2003'd,'30/360'); 408 put actual=days360=; 409 run; actual=365 days360=360 NOTE: “DATA 语句”所用时间(总处理时间): 实际时间 0.00 秒 CPU 时间 0.00 秒
例3.9 计算两个日期之间的年数
534 data _null;
535 sdate='16oct1998'd;
536 edate='16feb2003'd;
537 y3060=yrdif(sdate,edate,'30/360'); /*YRDIF()返回两个日期之间的年数*/
538 yactact=yrdif(sdate,edate,'ACT/ACT');
539 yact360=yrdif(sdate,edate,'ACT/360');
540 yact365=yrdif(sdate,edate,'ACT/365');
541 put y3060= yactact= yact360= yact365=;
542 run;
y3060=4.3333333333 yactact=4.3369863014 yact360=4.4 yact365=4.3397260274
NOTE: 数据集 WORK._NULL 有 1 个观测和 6 个变量。
NOTE: 压缩的数据集 WORK._NULL 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.01 秒
CPU 时间 0.01 秒
例3-10 以日为单位计算当前日期的天数
543 data;
544 x=date();
545 y=today();
546 put x= y=;
547 run;
x=20907 y=20907
NOTE: 数据集 WORK.DATA16 有 1 个观测和 2 个变量。
NOTE: 压缩的数据集 WORK.DATA16 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.02 秒
CPU 时间 0.01 秒
我们仍然可以使用一定的日期格式来表示他们:
548 data;
549 x=date();
550 y=today();
551 format x y yymmdd10.;
552 put x=y=;
553 run;
x=2017-03-29 y=2017-03-29
NOTE: 数据集 WORK.DATA17 有 1 个观测和 2 个变量。
NOTE: 压缩的数据集 WORK.DATA17 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.04 秒
CPU 时间 0.00 秒
例 3-11 以秒为单位计算当前的日期和时间
590 data;
591 n=datetime();
592 put n=;
593 x=datetime();
594 put x=;
595 format x datetime20.4; /* datatime20.4为时间变量输出格式*/
596
597 y=datetime();
598 put y;
599 format y nldatm20.; /* nldatm20.为日期时间变量输出格式*/
600
601 m=time();
602 put m=;
603
604 z=time();
605 put z=;
606 format z hhmm8.2;
607 run;
n=1806425804.5
x=29MAR17:16:56:44.453
2017-03-29 16:56:44
m=61004.492
z=16:56.74
NOTE: 数据集 WORK.DATA19 有 1 个观测和 5 个变量。
NOTE: 压缩的数据集 WORK.DATA19 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.10 秒
CPU 时间 0.01 秒
例3-12 计算日期值所在的年季月以及处于某月的第几天
635 data a;
636 set ResDat.stk000001(obs=10);
637 keep date year qtr month day;
638 year=year(date);
639 qtr=qtr(date);
640 month=month(date);
641 day=day(date);
NOTE: 从数据集 RESDAT.STK000001. 读取了 10 个观测
NOTE: 数据集 WORK.A 有 10 个观测和 5 个变量。
NOTE: 压缩的数据集 WORK.A 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.01 秒
CPU 时间 0.01 秒
642 proc print noobs;
643 run;
NOTE: 从数据集 WORK.A. 读取了 10 个观测
NOTE: “PROCEDURE PRINT”所用时间(总处理时间):
实际时间 0.01 秒
CPU 时间 0.01 秒
例3.13 计算当前时间的小时数和分钟数
644 data;
645 h=hour (datetime());put h=;
646 m=minute(datetime());put m=;
647 run;
h=17
m=19
NOTE: 数据集 WORK.DATA20 有 1 个观测和 2 个变量。
NOTE: 压缩的数据集 WORK.DATA20 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.01 秒
CPU 时间 0.01 秒
例 3-14 将日期时间值换算为以秒计数的计算方法
680 data;
681 mdy=mdy(08,18,2001);
682 put mdy;
683 format mdy yymmdd10.;
684
685 hms=hms(21,50,51);
686 put hms=;
687 x=21*60*60+50*60+51;put x=;
688
689 dhms=dhms(date(),21,50,51);
690 put dhms=;
691
692 dhms=dhms(15263,21,50,51);
693 put dhms=;
694 y=15263*24*3600+x;put y=;
695 run;
2001-08-18
hms=78651
x=78651
dhms=1806443451
dhms=1318801851
y=1318801851
NOTE: 数据集 WORK.DATA23 有 1 个观测和 5 个变量。
NOTE: 压缩的数据集 WORK.DATA23 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.03 秒
CPU 时间 0.03 秒
3.5 概率分布函数
3.5.1 标准正态分布
1 data;
2 P1=probnorm(0);
3 P2=probnorm(1.96);
4 P3=probnorm(2.5758293);
5 put P1=P2=P3=;
6 run;
P1=0.5 P2=0.9750021049 P3=0.9949999999
NOTE: 数据集 WORK.DATA1 有 1 个观测和 3 个变量。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.00 秒
CPU 时间 0.01 秒
3.5.2卡方分布
PROBCHI(X,DF,NC)
计算自由度为DF,非中心参数为NC的卡方分布随机变量小于X的概率。
计算:
315 data;
316 P=1-Probchi(31,88,11);
317 put P=;
318 run;
NOTE: 禁用了数据集 WORK.DATA2 的压缩,因为压缩的系统开销将增大数据集的大小。
P=0.9999999999
NOTE: 数据集 WORK.DATA2 有 1 个观测和 1 个变量。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.04 秒
CPU 时间 0.01 秒
3.5.3伽马分布
PROBGAM(X,A)
计算形状参数A的伽马分布随机变量小于X的概率
319 data;
320 P=Probgam(7.5,5.2);
321 put P=;
322 run;
NOTE: 禁用了数据集 WORK.DATA3 的压缩,因为压缩的系统开销将增大数据集的大小。
P=0.848853533
NOTE: 数据集 WORK.DATA3 有 1 个观测和 1 个变量。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.00 秒
CPU 时间 0.01 秒
3.5.4贝塔分布
PROBBETA(X,A,B)
其中 :X在[0,1]之间,A>0 ,B>0
计算形状参数
1 data;
2 P=Probbeta(0.75,4,2.5);
3 put P;
4 run;
0.7467346191
NOTE: 数据集 WORK.DATA1 有 1 个观测和 1 个变量。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.01 秒
CPU 时间 0.01 秒
3.5.5F分布
PROBF(X,NDF,DDF,NC)
计算自由度为32和2,非中心参数为30的F分布小于3的概率。
9 data;
10 P=1-Probf(3.32,2,30);
11 put P=;
12 run;
P=0.0498295363
NOTE: 数据集 WORK.DATA3 有 1 个观测和 1 个变量。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.01 秒
CPU 时间 0.01 秒
3.5.6t分布
PROBBNML(p,n,m)
其中自由度为DF,非中心参数为NC的t分布随机变量小于X的概率,默认时NC=0,即中心t分布,自由度DF可以是非整数。双边t检验显著水平的计算公式:
(1-probt(abs(x),df))*2)
例3.20 计算自由度为6的中心t分布绝对大于2.8的概率
13 data;
14 P=(1-probt(abs(-2.8),6))*2;
15 put P=;
16 run;
P=0.0311639481
NOTE: 数据集 WORK.DATA4 有 1 个观测和 1 个变量。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.03 秒
CPU 时间 0.03 秒
3.7样本统计函数
3.7.1均值
MEAN(of x1-xn) 或 MEAN(x,y,z,...)
计算非缺失值自变量的算术平均值。自变量中至少有一个非缺失量。
3.7.2最大值
MAX(of x1-xn) 或 MAX(x,y,z,...)
计算非缺失值自变量中的最大值,自变量中至少有两个非缺失值。
3.7.3最小值
MIN(of x1-xn) 或 MIN(x,y,z,...)
计算非缺失值自变量中的最小值,自变量中至少有两个非缺失值。
3.7.4非缺失数据个数
N(of x1-xn) 或 N(x,y,z,...)
3.7.5缺失数据个数
NMISS(of x1-xn) 或 NMISS(x,y,z,...)
3.7.6求和
SUM(of x1-xn) 或 SUM(x,y,z,...)
3.7.7方差
VAR(of x1-xn) 或 VAR(x,y,z,...)
3.8随机数函数
3.9SAS CALL子程序
3.9.2 随机数子程序
用随机数子程序可以更好的控制种子流和随机数流。
CALL语句激活随机数子程序的格式为:
CALL routine (seed),<argument,>variate);
选项说明:
例3.38 使用随机函数产生两个随机数变量属于同一个随机数
323 data RV;
324 retain seed1 seed2 161321804;
325 do I=1 to 5;
326 x1=ranuni(seed1);
327 x2=ranuni(seed2);
328 output;
329 end;
330 options nocenter;
NOTE: 数据集 WORK.RV 有 5 个观测和 5 个变量。
NOTE: 压缩的数据集 WORK.RV 增大了 100.00%。
压缩为 2 页;不压缩将需要 1 页。
NOTE: “DATA 语句”所用时间(总处理时间):
实际时间 0.02 秒
CPU 时间 0.04 秒
331 proc print;
NOTE: 正在写入 HTML Body(主体)文件: sashtml.htm
332 run;
NOTE: 从数据集 WORK.RV. 读取了 5 个观测
NOTE: “PROCEDURE PRINT”所用时间(总处理时间):
实际时间 0.30 秒
CPU 时间 0.21 秒
声明:
以上学习笔记来自
《SAS编程技术教程》朱世武 编著 清华大学出版社