嗯,最近在学习宏真得有点难度,不过似乎现在大体系统了解了这块知识,所以,就今晚进行一个整理归纳~
一、宏功能
1)可以降低重复性任务的工作量,便于重复调用。
2)使程序模块化,同时便于修改宏参数,而无需重新运行,可以大幅提高运行效率。
二、宏变量
无论在哪一个语言中,变量的地位是毋庸置疑的,在sas宏也是如此。
2.1 宏定义
定义宏的方法主要有三,分别是let定义、data步定义以及sql步定义。
1)%LET定义
%let myname=LGD;
%put "My name is &myname.";
输出:"My name is LGD"
2)data步定义
语法过程:call symput("宏变量名",值);
语法过程:call symputx(“宏变量名”,值,宏变量作用域);
data _null_;
set sashelp.class(obs=6 firstobs=6);
call symput('myname',name);
call symput('myage',age);
run;
%put "My name is &myname Bond, I'm &myage years old.";
输出:"My name is James Bond, I'm 12 years old."
data _null_;
set sashelp.class(obs=6 firstobs=6);
call symputx('myname',name);
call symputx('myage',age);run;
%put "My name is &myname Bond, I'm &myage years old.";
输出:"My name is James Bond, I'm 12 years old."
可以看出,symput输出的结果中会存在很多的空格,到底为什么会产生我还要研究,但是symputx输出的结果就是把多余的空格都去掉的。
3)SQL过程中定义
语法过程为:
proc sql noprint;
select name,sex into: myname,:mysex
from sashelp.class(firstobs=1 obs=1);
quit;
%put "Name is &myname, Sex is &mysex .";
输出:"Name is Alfred , Sex is M ."
2.2 宏显示
主要就是用%put语句显示宏变量
语法格式:%put <TEXT | _ALL_ | _AUTOMATIC_ | _GLOBAL_ | _LOCAL_ | _USER_>;
2.3 宏引用
而关于宏的引用,主要分3类,分别为直接引用、间接引用和隔开引用。
1)直接引用
这个直接引用有3点需要注意,分别有三个例子。
%let x=30;
data a;
x=&x.;*带后缀句点会更加安全;
run;
%let x=30;
data a;
x="It's &x.";*带引号的文本中引用宏变量,必须使用双引号;
run;
%let 区域=%nrstr(华东&华南);*若引用内容存在&符号,则需要用到nrstr;
%put &区域.;
2)间接引用
顾名思义就是通过一些过程之后才引用宏函数,其实最常见的就是在宏名称那里大搞动作,sas宏中就有一个机制,就是&&&运行一次,会变成&&,再运行一次会变成&,大家还是看下例子。
%let app1=A001;
%let app2=A002;
%let app3=A003;
%let i=2;
%put &&app&i;
输出:A002
可以看出,第一次运行的时候,&&变成&,&i变成2,然后就重新组合成&app2,然后就调用返回A002
3)隔开引用
这个炒鸡建议大家使用,就是在你引用宏变量名称的时候,默认在后面加上个”. ”,这样子会避免很多问题。大家可以从下面的例子中看出:
%let myvar=here;
%put &myvar100;
%put &myvar.100;
输出:
WARNING: 没有解析符号引用 MYVAR100。*明显,没有用逗号隔开的,系统会默认是一个整体,所以把myvar100看出一个整体,然而这个宏并没有被定义,所以就调用失败;
here100*这个为正确示范;
所以还是建议大家在引用宏的时候,在最后加上一个逗号来隔开后面的内容。
三、宏函数
3.1 定义宏
3.2 调用宏
调用宏很简单,就是以“%macro_name;”格式来调用宏程序,但调用前,要先运行一次宏程序。
3.3 宏参数
宏参数用的机会是很多的,宏参数创建的方式主要有2种。一种是按值创建,另一种是按地址创建。
1)按值创建宏参数
当参数超过一个时,参数的位置可以任意放
%macro t(name=,age=);
data _null_;
put "I'm &name, I'm &age years old.";
run;
%mend;
%t(name=yy,age=20);
%t(age=20,name=yy);
输出结果(2个都一样的):I'm yy, I'm 20 years old.
2)按地址创建宏参数
参数的位置要按宏定义的位置放
%macro t(name,age);
data t;
name="&name";
age=&age;
put "I'm &name, I'm &age years old.";
run;
%mend;
%t(yy,20);
%t(20,yy);
输出结果:I'm yy, I'm 20years old.
I'm 20, I'm yy years old.
可以看出,你输入的变量需要按照顺序来,不然的话就会出现预想之外的结果。
3.4 通配函数
通配函数是指能够在SAS宏中使用data步的函数,最常用的通配函数是%SYSFUNC函数。
语法格式:%sysfunc(function(argument(s))<,format>);
例子:
*Fromat应用;
%put today is %sysfunc(putn('11oct2015'd,yymmdd10.));
*判断数据集是否存在;
%put %sysfunc(exist(work.aaa_4));
3.5 计算函数
宏计算函数有两个,均可计算算术和逻辑表达式
1)%EVAL函数:整数格式计算
语法格式:%EVAL (arithmetic or logical expression)
%let a=3+2;
%put %eval(&a);*返回5;
%put %eval(3+2);*返回5;
%put %eval(3.1+2);*如果是带有小数的计算,将会报错;
%put %eval(10/3);*如果是做除法运算,结果只会保留整数;
2)%SYSEVAL函数:浮点格式计算
语法格式:%SYSEVAL(expression<, conversion-type>)
conversion-type包括下表所示内容:
*boolean;
%put %sysevalf(1/3,boolean); /* returns 1 */
%put %sysevalf(10+.,boolean); /* returns 0 */
*ceil;
%put %sysevalf(1 + 1.1,ceil); /* returns 3 */
*floor;
%put %sysevalf(-2.4,floor); /* returns -3 */
*integer;
%put %sysevalf(2.1,integer); /* returns 2 */
%put %sysevalf(-2.4,integer); /* returns -2 */
四、宏语句
其实和我们平时在data步中使用的函数差不多,只不过都加了特殊标志%,常用的语句如下所示:
4.1 %if-%then /%else语句
语法格式:%IF expression %THEN action;
%ELSE action;
%macro t(workday=);
%if &workday=1 %then %do;
%workmacro;
%end;
%else %do;
%put 今天休息,不运行程序;
%end;
%mend;
4.2 %do循环语句
语法格式:
%do start %to stop<%by increment>;
文本及宏语句;
%end;
%macro t(n=);
%do i=1 %to &n;
proc append base=basedata data=newdata&i.;run;quit;
%end;
%mend;
4.3 %do %while循环语句:条件为真时执行
语法格式:
%do %while(expression);
文本及宏语句;
%end;
%macro t(n=);
%let i=1;
%do %while (&i<=&n);
proc append base=basedata data=newdata&i.;run;quit;
%let i=%eval(&i+1);
%end;
%mend;
4.4 %do %until循环语句:条件为真时结束执行
语法格式:
%do %until(expression);
文本及宏语句;
%end;
%macro t(n=);
%let i=1;
%do %until(&i>&n);
proc append base=basedata data=newdata&i.;run;quit;
%let i=%eval(&i+1);
%end;
%mend;
以上是对sas宏比较常用的内容进行系统的梳理,当然有很多内容是忽略了的,sas宏的理论知识讲太多的话其实也记不得多少呢,所以未来2天我会post几个关于sas宏的案例,一遍解析思路和sas宏的实际应用,敬请期待~嘻嘻!