sas宏变量与数据集之间的交互

在目前的数据处理过程中,我们面对的处理对象主要是二位数据表即sas数据集,但是我们在写宏程序时,宏变量和红参数又是字符串的形式,所以我们需要探讨一下宏变量和红参数怎么和数据集之间进行交互。

将数据集集名、变量名、变量值、变量label、变量类型等以单个值或者多个值拼接的形式传给宏变量。

将宏变量的值作为生成数据集的代码与数据集代码进行拼接。

 转载注明出处:http://www.cnblogs.com/SSSR/p/6908521.html 

一、生成宏变量的三种方式

1.%let

%let day=Friday;/*作为一些自定义变量*/
%put dayis:&day;

这里需要说明一下,Friday没有加引号,这个也是因为宏的目的是为了拼接程序,而在写程序中一般是没有引号的,只有在使用变量值的时候或者函数参数时才会有引号,当我们遇到这些时使用||进行拼接即可,或者使用"&var.",

在双引号中&是生效的,但是在单引号中是不生效的。

 

2.symput或symputx函数

data步中产生新变量, 宏变量的命名规则按照普通sas宏变量的规则,但需要加上对称引号,两者的区别symputx被赋值数值时可以删除补空的首空格,其作用为trim+symput函数。

若宏变量被赋的可以是文本常量,如call symput("gender","Imformation for male");文本需加引号,也可以是data步某变量的当前值如call symput("gender",sex);

data test4;
set sashelp.class;
if Sex="M" then do ;
output;
call symput("gender","Imformation for male");
end;
run;
proc print;
title "&gender"; /*调用gender宏变量*/
run;

 

3.select into

这个最常用的就是讲sas的数据集的变量名赋给宏变量,以供其他程序使用。

data a;
input name $ id sex $ num1 var1 $ num2 var2 $ var3 var4 $;
cards;
a 1 m 3 x 5 y 7 z
;
run;
proc print;
run;

/*这个是通过空格间隔的,在data步和proc步中使用*/
proc sql;

select name into :vars separated by ' '
from dictionary.columns
where memname='A';
quit;

/*这个是用逗号间隔的,在select语句中使用。*/
proc sql;

select name into :vars1 separated by ','
from dictionary.columns
where memname='A';
quit;
%put &vars.;
%put &vars1.;

 

 

二、在data步中使用宏变量

1.symget

该函数作为data步变量值与宏变量的桥梁,symget(day)是data步day变量的每个值作为一个宏变量,调用全局宏变量表的相应的宏变量的值。如day的day1值对应的宏变量day1的值为Monday,

所有最后data 的day变量的day1为Monday。该函数的作用相当于if的作用,ifday=”day1” then day=”Monday”;使用上语句简单,不容易出错逻辑上的遗漏或重叠等错误。

%let day1=Monday;
%let day2=Tuesday;
%let day3=Wednesday;
data test3;
input day $ plan : & $10.;
day=symget(day);
cards;
day1 zoo
day2 sea world
day3 park
;
run;

 

2.将宏变量的值写入数据集

下面的两个例子,如果我们定义%let a=1 q 2 w 3;则就是将宏变量的值存入数据集中的方法。

这两个例子还解决了相同名称的数据集循环set的问题,不用首先写一个空数据集了。

例子1:


%macro test;
%do i = 1 %to 5;
%let x&i. = %scan(1 q 2 w 3,&i.);

data collect;
length x $20.;

x = "&&x&i..";
i = &i.;
run;

proc append base = all data = collect;
quit;
%end;
%mend;
%test;

用append可以免去新建base数据集的麻烦;但是小心如果本身all就存在,他会把all直接拿来用。也可以用SQL的insert来插值。

 

例子2:

%macro test;
%do i = 1 %to 5;
%let x&i. = %scan(1 q 2 w 3,&i.);

data collect;
length x $20.;
%if &i. > 1 %then %do;/*是否为第一次新建*/
set collect end = last;
output;

if last then do;
%end;
x = "&&x&i..";
i = &i.;
output;

%sysfunc(ifc(&i. > 1,end;,))
run;
%end;
%mend;
%test;

 这个里用了%if条件判断,是否为第一次新建数据。

以下是第2次的宏解析出的语句:

data collect;
length x $20.;/*定义长度*/
set collect end = last;/*end=last 就是对数据集最后一条记录打个标记,以判断是否到达最后一条观测。SAS 是行读入机制,如果读到最后一行这个标记为1否则为0*/
output;/*使用这个output的原因,是因为在if语句中含有output,如果代码中有了output,那么所有的输出都要通过ouput显示输出,默认输出将会关闭,这里是set语句中的pdv一行一行的输出。*/
if last then do;/*判断如果是最后一条记录了,则执行下面的语句。*/
x = "q";
i = 2;
output;/*显式输出。*/
end;
run;

 

 

 

三、宏变量的间接引用(多个&)

解析规则个人总结为:从左至右,相邻两&变一个&,每轮组合若有落单的&宏变量解析一次。如下列值第一次扫描,左两组合变为1个&,该轮扫描第三个&落单,即解析&day为day1,此时为%put&day1;day1解析为day2。

再如%put&&&&&&&day;7个&,第一轮解析,左六相邻6个&两两组合变变成三个&&&,落单一个&则解析,结果为%put &&&day1,第二轮为%put &day2,第三轮则为day3。 

例子:

%let day=day1;
%let day1=day2;
%let day3=day4;
%put &&&day;

 

posted on 2017-05-26 16:11  徐长卿学数据分析  阅读(2336)  评论(1编辑  收藏  举报