有人說把sas宏比作其他語言的函數,但是我做此類比的時候陷入了死胡同,沒有成功,舉一例,如果是函數就要有返回值,sas宏的返回又是什么。而且sas宏涉及到編譯階段,導致很難理解。
直到看到了一個人說,宏是幫你寫程序的程序,才有那么點感覺。
如果真的是這樣,我們的程序其實就是一段文本,傳給后台,然后運行。類似於在sql中我們是用execute函數來執行一段被引號括起來的sql語句。
所以我們是否可以把宏當做文本編輯語言,或者最直接的就是一個字符串編輯語言,編輯生成一個字符串,然后將字符串提交給后台進行運行。
舉個例子:
%let x=%str(data a;set sashelp.class;run;);
%PUT &x.;
&x.;
這段代碼可以直接運行,而且生成了數據集A,那么這里的宏變量x其實就是一段可執行的sas代碼,使用%str()是為了以防sas解析時認為;是句子的分隔符。
再看下一段代碼:
%let x=%str(data r;);
%let y=%str(set sashelp.class;);
%let z=%str(run;);
%let s=&x.&y.&z.;
&s.;
這個的字符串拼接其實就非常明顯了。
錯誤:ERROR: Open code statement recursion detected.
解決方法:單獨執行run; quit;等即可。
一個新的更改數據集變量順序的方法,其中心思路也是拼接程序:
varnum是變量順序。
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;
proc sql;
create table vars as
select varnum,name
from dictionary.columns
where memname='A';
quit;
data vars;
set vars;
if name='num2' then varnum=4.1;
run;
proc sql ;
select name into :a_vars separated by' '
from vars
order by varnum;
quit;
%put &a_vars.;
data a;
retain &a_vars.;
set a;
run;
proc print ;
run;
宏拼接字符串的難點在於單引號雙引號%&等特殊符號在何時應該被解析,我們提交給sas后台的代碼不像其他語言那樣是帶有雙引號或者單引號的!
今天先寫到這里,后面我會進行更多的試驗,把這方面的內容從理論和實際方面補齊。