1.一些内建宏变量
两个有用的宏变量分别是&SYSDATE9和&SYSTIME。前者告诉你日期,后者保存有时间。如
title "The Date is &sysdate9 - the Time is &systime";
proc print data=learn.test_scores noobs;
run;
注意,宏变量只在引用在双引号,若在单引号下,并不会得到 解析。也就是说,在带有引号的文本中引用宏变量时,需要将这个文本字符串用双引号括起来。
2.以%LET赋值给宏变量
%let n = 3;
data generate;
do Subj = 1 to &n;
x = int(100*ranuni(0) + 1);
output;
end;
run;
title "Data Set with &n Random Numbers";
proc print data=generate noobs;
run;
%LET放在数据步的前面。每次程序运行时,&n被替换为3.
宏变量被定义后,就可以通过在其名称前使用&来对其进行引用。
3.简单宏
宏以%MACRO开始,以%MEND结束。现在想修改上一个例程,使之能更通用。不仅能修改随机数的个数,还能改变开始值和结束值。代码如下
%macro gen(n,Start,End);
data generate;
do Subj = 1 to &n;
x = int((&End - &Start + 1)*ranuni(0) + &Start);
output;
end;
run;
proc print data=generate noobs;
title "Randomly Generated Data Set with &n Obs";
title2 "Values are integers from &Start to &End";
run;
%mend gen;
宏GEN有三个参数,分别为n,Start,End.为了产生4个从1到100的随机数,调用如下
%gen(4,1,100)
调用宏时,用一个%加宏名字就可以调用该宏。后面无需分号。
解析宏变量有一个需要值得注意的地方。假设有一段代码如下
%let prefix = abc;
data &prefix123;
x = 3;
run;
你的本意是产生一个名为Abc123的数据集。实际执行时却产生错误,SAS认为你要产生的数据集名为prefix123了。解决方法是在prefix后加一个点。如
%let prefix = abc;
data &prefix.123;
x = 3;
run;
4.通过宏变量在数据步之间传值
宏只在data步和proc步间起作用。如果想用数据步产生的信息值创建宏变量,以便于在后面的程序中使用。可以用到Symput和sysmget子程序。
例如,假设你已经用proc means计算了变量的平均值,现在想比较每个观测值与平均值的差异。示例如下
proc means data=learn.blood noprint;
var RBC WBC;
output out=means mean= M_RBC M_WBC;
run;
data _null_;
set means;
call symput('AveRBC',M_RBC);
call symput('AveWBC',M_WBC);
run;
data new;
set learn.blood(obs=5 keep=Subject RBC WBC);
Per_RBC = RBC / &AveRBC;
Per_WBC = WBC / &AveWBC;
format Per_RBC Per_WBC percent8.;
run;
proc means产生一个名为Means的数据集,包含了M_RBC和M_WBC两个变量,分别表示RBC和WBC的平均值。
Data_NULL_步使用了SYMPUT,以把Data步的值赋给宏变量。不能使用%LET,因为不知道M_RBC和M_WBC的值。SYMPUTU的第一个参数是想创建的宏变量的名字,第二个参数是想赋给宏变量的值。一旦此步执行,两个宏变量将得到其平均值。
最后,介绍宏程序设计语句
%* 宏注释语句
%do 条件处理至一个匹配的%end语句
%do %until 重复循环直到条件为真
%do %while 重复循环
%global 创建全局宏变量
%if %then %else 条件执行语句
%input 为宏变量提供值
%let 创建宏变量
%macro 定义宏
%mend 结束宏定义
%macro-name 调用宏
%put 输出文件到log窗口
宏函数
%Eval 计算算术和逻辑表达式,整数格式
%sysevalf 计算算术和逻辑表达式,浮点格式
%length 返回自变量的长度
%Bquote 引用一个可分辨的值,不包括未处理的特殊符号和寄存器操作符。
%Nrbquote 引用一个可分辨的值,包括未处理的特殊符号和寄存器操作符。
%Nrquote 引用一个可分辨的值,包括&和%
%Nrstr 引用固定文本,包括%和&
%Quote 引用一个除%和&之外的可分辨值
%str 引用除%和&之外的固定文本
%Superq 引用具有不确定变量值的宏变量
%Unquote 没有被引用