SAS (统计分析软件)课件:第14章 宏编程技术.ppt
52页第第14章章 宏编程技术宏编程技术本章内容包括: §概述;•宏变量;•宏;•宏参数;•宏表达式;•宏引用;•宏工具中的输入输出;•数据步接口程序;•宏程序语句和宏函数概述§宏工具是一种可以用来扩展SAS功能,减少普通工作文本输入量的SAS工具宏工具可以给一段文本或SAS程序命名,并通过引用这个名称来使用这段程序或文本宏工具的功能非常强大,使用宏工具来完成以下任务§ 使用宏变量实现文本替代;§ 使用宏产生程序语句;§ 使用宏循环及条件判断语句完成程序交互 宏变量 §定义宏变量定义宏变量§用宏程序语句%LET来定义宏变量§%let DSN=ResDat.class;§例中,DSN是宏变量名,ResDat.class为宏变量DSN的值 引用宏变量 §在宏变量前加&来引用宏变量的值§ §例14.1 引用宏变量A§%let a=ResDat.class;§data a;§set &a ;§run;§上段程序等价于:§data a;§set ResDat.class;§run;§例14.2 宏处理器只能在双引号内进行替代§%let a=january;§data;§put "This is the time series plot for &A";§run;§例中,在引号内引用宏变量的值时必须用双引号。
因为宏处理器只能在双引号内进行替代606 %let a=january;607 data;608 put "This is the time series plot for &A";609 run;This is the time series plot for januaryNOTE: 数据集 WORK.DATA1 有 1 个观测和 0 个变量NOTE: “DATA 语句”所用时间(总处理时间): 实际时间 0.01 秒 CPU 时间 0.01 秒§例14.3 多次引用宏变量§%let a=ResDat.class;§data male;§set &a ;§if sex='M';§proc print;§title "SUBSET OF &A";§data female;§set &a ;§if sex='F';§proc print;§title "SUBSET OF &A";§run;§例14.4 改变宏变量的值§%let m=2000;§%let n=1;§data a;§set ResDat.stk000002;§where year(date)=&m and month(date)=&n;§年 &n§proc gplot data=a;§title2 "&m 月份收盘价时序图";§plot clpr*date=1;§symbol1 v=star i=join r=1 c=red;§run;§例中,改变宏变量的值,如:%LET N=2,3,4,5,...,12可以分别得到12个月的时序图。
不过,更好的方法是用宏循环来实现这里的要求 §例14.5 宏变量的值为一段完整的SAS程序段§%let plot=%str(§proc gplot data=a;§plot clpr*date=1;§symbol1 v=star i=join r=1 c=red;§run; §);§例中,必须使用%STR函数围住宏变量的值,在以后的程序中可以用&PLOT来引用这段程序§%let m=2000;§%let n=1;§data a;§set ResDat.stk000002;§where year(date)=&m and month(date)=&n;§&plot;§title2 "&m 年 &n 月份收盘价时序图";§run;§例中,如果不执行宏&PLOT步的程序时,可将其设定为空值(%LET PLOT= ;) §例14.6 宏变量的嵌套引用§%let m=2000;§%let n=1;§%let xvar=date;§%let yvar=clpr;§%let plot=%str(§proc gplot data=a;§title2 "&m 年 &n 月份收盘价时序图";§plot &yvar*&xvar=1;§symbol1 v=star i=join r=1 c=red;§run; §);§data a;§set ResDat.stk000002;§where year(date)=&m and month(date)=&n;§run;§&plot;§proc print;§title "&m 年 &n 月份收盘价";§run;如何隔开宏变量引用和文本l 在混合使用宏变量引用和文本的时候,会遇到宏变量后面紧跟着文本的情况。
l 如定义宏变量name后,当使用&name1,&name2时,如果不定义name1和name2这两个宏变量,系统就会提示这两个宏变量并不存在,因为在SAS识别宏变量的时候,自动将name1和name2当成了宏变量的名称 l 在宏的引用过程中,当词段扫描器识别一个宏变量名称时,从&开始直到遇到一个SAS名称中不允许出现的字符为止所以空格等一些不允许出现在SAS名称中的字符就可以作为分隔符出现,但是为了不显示这些分隔符,一般使用句号来作为分隔符使用例14.7 隔开宏变量引用和文本let name=Resdat;%PUT &name^1;%put &name.1;%put &name..sheet;/*日志窗口信息 */12 %let name=ResDat;13 %PUT &name^1;ResDat^114 %put &name.1;ResDat115 %put &name..sheet;ResDat.sheet显示宏变量值 §显示宏变量的最简单方法是使用%put语句,它将文本输出到SAS的日志窗口§语句格式:§%PUT
§data _null_;§%let a=first;§%let b=macro variable;§%put &a !!! &b !!!;§run;§LOG窗口显示:§first !!! macro variable !!!间接引用宏变量§对一系列的宏变量引用,如data1,data2, data3, 这一系列中部分文本是固定的名称,而另一部分是变化的数字这时就可以采取间接引用方式§例14.9 间接引用宏变量§%let data1=x;§%let data2=y;§%let data3=z;§%macro test;§ %do i=1 %to 3 ;§ %put &&data&i;/*&data&i不能用*/§ %end;§%mend test;§%test宏变量范围l宏变量以使用范围分为全局宏变量和局部宏变量l全局变量可以在SAS对话运行期间使用并且可以在程序的任何地方引用l局部变量则只能在创建该局部变量的宏中使用,在这个宏之外,这个局部变量就没有任何意义宏 §宏是被编辑过的可以从SAS程序中调用的程序同宏变量一样,一般可以使用宏来产生文本§§定义宏的格式:§%Macro MAC;§文本;§%mend MAC;§例14.10 定义宏plot。
§%macro plot;§proc gplot data=ResDat.stk000002;§title2 "收盘价时序图";§plot clpr*date=1;§symbol1 v=star i=join r=1 c=red;§%mend plot;调用一个宏 §用一个百分号(%)加宏名字就可以调用该宏§ §例14.11 定义并调用宏plot§%macro plot;§proc gplot data=ResDat.stk000002;§title2 "收盘价时序图";§plot clpr*date=1;§symbol1 v=star i=join r=1 c=red;§%mend plot; /*以上定义宏plot*/§%plot; /*调用宏*/§run;改变宏内宏变量的值 §例14.12 改变宏内宏变量的值,分以下几步完成§定义宏plot:§%macro plot;§proc gplot data=ResDat.&dat;§title2 "&pr 时序图";§plot &price*date=1;§symbol1 v=star i=join r=1 c=red;§%mend plot;§定义宏变量:§%let dat=stk000002;§%let pr=收盘价;§%let price=clpr;§调用宏plot:§%plot;§改变宏变量的值:§%let dat=stk000002;§%let pr=最高价;§%let price=hipr;§ 再次调用宏plot:§%plot; §run;§以上各段程序可以连在一起运行。
宏参数 § 宏变量和宏结合在一起是一种强有力的编程方法但应用起来并不十分方便最常用的是在宏中使用宏参数§ 宏参数是一种特殊的宏变量,是定义在宏%MACRO语句内的宏变量§例14.13 创建宏参数§%macro plot(dat,pr,price);§proc gplot data=ResDat.&dat;§title2 "&pr 时序图";§plot &price*date=1;§symbol1 v=star i=join r=1 c=red;§%mend plot;§例中,在%MACRO语句括号内定义的宏变量DAT, PR和PRICE称为宏参数 §例14.14 通过给宏参数赋值来调用宏§%plot(stk000002, 收盘价,clpr);§例中,运行时,宏处理器把第一个值(stk000002)赋给第一个宏参数DAT,第二个值(收盘价)赋给第二个宏变量PR,以此类推§使用宏参数的优点:§ 可以少写几个%let语句;§ 保证该宏参数变量在宏之外的程序部分不被引用;§ 调用宏时并不需要知道这些宏参数的名字,只要知道相应的取值宏参数赋值 §例14.16 创建宏参数时直接赋值。
§%macro plot(dat=stk000002, pr=收盘价,price=clpr);§proc gplot data=ResDat.&dat;§title2 "&pr 时序图";§plot &price*date=1;§symbol1 v=star i=join r=1 c=red;§%mend plot;§%plot;§run; §例14.17 运行宏时赋值§%macro plot(dat,pr,price);§proc gplot data=ResDat.&dat;§title2 "&pr 时序图";§plot &price*date=1;§symbol1 v=star i=join r=1 c=red;§%mend plot;§%plot(stk000002, 收盘价,clpr);§%plot(stk000002, 最高价,hipr);§run;宏调用宏§产生数据集宏:.§%macrocreate;§datatemp;§setResDat.&dat;§ifyear(date)=&year;§%mendcreate;§画时序图宏:§%macroplot;§procgplotdata=temp;§title2"&pr&year1时序图";§plot&price*date=1;§symbol1v=stari=joinr=1c=red;§%mendplot;§run;宏调用宏:%macro analyze(dat, year, pr,price,year1);%create; /*产生数据集TEMP*/%plot; /*作图*/%mend analyze;运行宏:%analyze(stk000002, 2000, 收盘价,clpr,2000);run;条件表达式 §例14.19 用条件表达式%if-%then定义宏。
§%macro analyze(getdata, dat, year, pr,price,year1);§%if &getdata=yes %then %create;§%plot;§%mend analyze;§%analyze(yes, stk000002, 2000, 收盘价,clpr,2000);§%analyze(no, stk000002, 2000, 最高价,hipr,2000);§run;生成重复文本 §例14.22 定义生成重复文本宏§%macro names(name, number);§%do n=1 %to &number;§&name&n§%end;§%mend names;§例中,宏names通过宏参数name,number和宏变量n可以生成一系列的名字§在DATA语句中调用宏NAMES:§data %names(dsn, 5);§run;§产生下列data步语句:§DATA DSN1 DSN2 DSN3 DSN4 DSN5; 620 %end;621 %mend names;622 data %names(dsn, 5);623 run;NOTE: 数据集 WORK.DSN1 有 1 个观测和 0 个变量。
NOTE: 数据集 WORK.DSN2 有 1 个观测和 0 个变量NOTE: 数据集 WORK.DSN3 有 1 个观测和 0 个变量NOTE: 数据集 WORK.DSN4 有 1 个观测和 0 个变量NOTE: 数据集 WORK.DSN5 有 1 个观测和 0 个变量NOTE: “DATA 语句”所用时间(总处理时间): 实际时间 0.06 秒 CPU 时间 0.04 秒LOG窗口显示:宏引用§使用%STR或%NRSTR在宏编译阶段可以屏蔽掉一些特殊字符,避免这些特殊字符影响宏处理器组建宏语句的方式§例14.24使用%STR或%NRSTR来屏蔽一个单个的单引号或双引号或括号时,特殊字符前加上%号§%lettest1=%STR(Mrsmith’shouse);/*出现错误*/§Quit;§%lettest2=%STR(Mrsmith%’shouse);§%put&test1&test2;数据步接口程序 v宏处理器只在DATA步或PROC步的编译期间起作用如果想用数据步产生的信息值创建宏变量,以便于在后面的程序中使用,可以用下面的编程技术。
数据步接口程序 §下面两个接口程序可在DATA步执行期间创建宏变量,指定它们的值,及重新得到它们的值§ 数据步接口程序§例14.28 由数据步产生的信息值创建宏变量§%macro create;§data temp;§set ResDat.&dat end=final;§if year(date)=&year then §do;§n+1;§output;§end;§if final then call symput('number', n); /*创建的宏变量为number,其值为n*/§run;§%mend create;§%macro plot;§proc gplot data=temp;§title2 "&pr &year1 时序图";§plot &price*date=1;§symbol1 v=star i=join r=1 c=red;§%mend plot;§run;§%macro analyze(getdata, dat, year, pr,price,year1);§%if %upcase(&getdata)=YES %then %create;§footnote "Plot of &number Observations";§%plot;§%mend analyze;§%analyze(yes, stk000002, 1999, 收盘价,clpr,1999);§%analyze(yes, stk000002, 2000, 收盘价,clpr,2000);§%analyze(yes, stk000002, 2001, 收盘价,clpr,2001);§run;v 例中,由于SYMPUT子程序用BEST12.的格式输出N的值,故NUMBER的值居右。
为了使该值居左,在SYMPUT子程序中使用LEFT函数宏程序语句和宏函数 v 宏功能包括很多宏程序语句和宏函数下面列出部分SAS系统有效的宏程序设计语句和宏函数 宏程序设计语句及用途 语句用途%Do条件处理至一个匹配的%END语句%Do%Until重复循环直到条件为真%End结束%DO组%Global创建全局宏变量%If-%Then/%Else有条件执行宏%Input为宏变量提供值%Let创建宏变量%Macro-Name调用宏%Macro定义宏%Mend结束宏定义%Put输出文件到LOG窗口宏函数 §宏计算函数宏计算函数函数名说明%Eval计算算术和逻辑表达式 整数格式%SYSEVALF 计算算术和逻辑表达式 浮点格式宏引用函数 函数名说明%Nrstr引用固定文本,包括%和&%Quote引用一个除%和&之外的可分辩值%Str引用除%和&之外的固定文本§例14.30 用%EVAL函数计算宏表达式的值§data;§%let x=100;§%let y=%eval(&x+200);§%let z=&x+200;§%put y=&y z=&z;§run;§提交上述程序后,Log窗口显示的结果为:§y=300 z=100+200§例中,宏变量Y的值是一数值,而宏变量Z的值是字符串”100+200”。
§例14.31 用%substr函数生成某字符串的子串§data %substr(&sysday,1,3);§run; 47 data %substr(&sysday,1,3);48 run;NOTE: 数据集 WORK.FRI 有 1 个观测和 0 个变量NOTE: “DATA 语句”所用时间(总处理时间): 实际时间 0.09 秒 CPU 时间 0.00 秒LOG窗口显示例14.32 用%QOUTE函数引用一个可分辩的值macro dept(X);%if %quote(&X)=fn %then%put Financial Department;%else %put other Department ;%mend dept;%dept(fn);%dept(math);run;49 %macro dept(X);50 %if %quote(&X)=fn %then51 %put Financial Department;52 %else %put other Department ;53 %mend dept;54 %dept(fn);Financial Department55 %dept(math);other Department56 run;LOG窗口显示。





