SAS函数与CALL子程序(二)

浏览: 2748
SAS

SAS函数与CALL子程序(二)

本章主要内容

  • 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编程技术教程》朱世武 编著 清华大学出版社

推荐 0
本文由 lingan 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册