SAS給宏變量賦值大體來說其實就3種方式:%let語句、data步中的call symput語句和proc sql過程中into語句堤魁。
這里根據(jù)變量和觀測的數(shù)量分情況進(jìn)行如下討論,即:
- 單變量單觀測變單宏變量
- 單變量單觀測變多宏變量
- 單變量多觀測變多宏變量
單變量單觀測變單宏變量
提出問題如下:
/*problem1:將組名信息賦值給宏變量group都弹,各組之間\分割,單變量一觀測變一宏變量*/
數(shù)據(jù)集如下:
data example1;
group = "太極組\圍棋組\古箏組\書法組";
run;
分別使用如下3種方法進(jìn)行宏變量賦值:
/*method1: let statement*/
%let group1 = 太極組\圍棋組\古箏組\書法組;
%put &group1.;
/*method2:data步 call symput statement*/
data _null_;
set example1;
call symput("group2",group);
run;
%put &group2.;
/*method3:proc sql statement*/
proc sql;
select group into: group3
from example1
;
quit;
%put &group3.;
- 說明
proc sql;
/* create table macros as*/
select *
from dictionary.macros
;
quit;
上述語句是獲得環(huán)境中macros變量信息的語句,很實用炬搭。
在單變量賦值單宏變量時,%let語句相比其他兩種要簡單穆桂,不必基于數(shù)據(jù)集宫盔;而proc sql語句則必須基于數(shù)據(jù)集中的變量產(chǎn)生;call symput則均可以實現(xiàn)享完。
單變量單觀測變多宏變量
- 問題
/*problem2:將組名信息分別依次賦值給宏變量term1灼芭,term2,...般又,單變量一觀測變多宏變量*/
- 數(shù)據(jù)集如下:
data example2;
group = "太極組\圍棋組\古箏組\書法組";
run;
分別使用如下3種方法進(jìn)行宏變量賦值:
/*method1: let statement*/
%let term1_1 = 太極組;
%let term1_2 = 圍棋組;
%let term1_3 = 古箏組;
%let term1_4 = 書法組;
%macro batch;
%do i = 1 %to 4;
%let _term1_&i. = %qscan("太極組\圍棋組\古箏組\書法組" , &i. , "\");
%end;
proc sql;
/* create table macros as*/
select *
from dictionary.macros
where scope = "BATCH"
;
quit;
%mend;
%batch;
/*method2:data步 call symput statement*/
data _null_;
set example2
do i = 1 to 4;
call symput(cats("term2_", put(i , best.)) , scan(group , i, "\") );
end;
run;
/*method3:proc sql statement*/
data m3;
set example2
array term (4) $ term1 - term4;
do i =1 to 4;
term(i) = scan(group , i, "\") ;
end;
run;
proc sql;
select term1, term2, term3, term4 into :term3_1 ,:term3_2 ,:term3_3,:term3_4
from m3
;
quit;
proc sql;
/* create table macros as*/
select *
from dictionary.macros
;
quit;
- 說明
- 這種情況就可以看出 %let語句的劣勢了彼绷,無法批量操作,為了批量操作我寫了個簡單宏才實現(xiàn)茴迁;
- call symput語句的實現(xiàn)則很簡單寄悯,這是因為只涉及到單個變量的操作,是data步的優(yōu)勢所在堕义,代碼量很少猜旬;
- 而proc sql給宏變量賦值的優(yōu)勢在這里體現(xiàn)的不明顯,但是也可以看出它針對數(shù)據(jù)集層面倦卖,批量化宏變量賦值操作的便捷性洒擦。
單變量多觀測變多宏變量
- 問題
/*problem3:將分組變量中組名觀測依次賦值給宏變量term1,term2怕膛,...熟嫩,單變量多觀測變多宏變量*/
- 數(shù)據(jù)集
data example3;
length group $200.;
input group;
cards;
太極組
圍棋組
古箏組
書法組
;
proc print;
run;
- 使用3種方法賦值宏變量
/*method1:%let statement*/
proc transpose data= example3 out=_out3;
var group;
run;
%macro m1;
data test;
set _out3;
call symput("group" ,catx("\", of col1 - col4) );
run;
%do i = 1 %to 4;
%let _1term_&i. = %qscan( "&group.", &i.,"\");
%end;
proc sql;
create table macros as
select *
from dictionary.macros
where scope = "M1"
;
quit;
%mend;
%m1;
使用%let解決這個問題,需要先轉(zhuǎn)置褐捻,使問題變?yōu)榛谧兞康簿褪橇幸蔚耍瑥浹a(bǔ)基礎(chǔ)語句基于觀測處理問題能力偏弱的短板;
然后構(gòu)建宏昧狮,在宏里還要再把數(shù)據(jù)集里的多個變量賦值為單個宏變量景馁,這是因為%let是在變量層面解決問題的,數(shù)據(jù)集無處下爪陵且;
之后使用循環(huán),彌補(bǔ)%let批量處理問題的短板个束。
/*method2:call symput statement*/
proc transpose data= example3 out=_out3;
var group;
run;
data M2;
set _out3;
array terms(4) col1 -col4;
do i = 1 to 4;
call symput(cats("_2term_", put(i , best.)),terms(i) );
end;
run;
proc sql;
select *
from dictionary.macros
;
quit;
- 說明
可以看到慕购,使用call symput解決這個問題,同樣需要經(jīng)歷轉(zhuǎn)置步驟轉(zhuǎn)變?yōu)樘幚碜兞康膯栴}茬底;然后在data步使用數(shù)組循環(huán)沪悲,還是比較繁瑣的。
- 而proc sql的優(yōu)勢就體現(xiàn)出來了阱表,一個代碼塊就達(dá)成目的殿如,如下:
/*method3:proc sql statement*/
/*單變量多觀測變多個宏變量*/
proc sql;
select group into :_3term1 -: _3term99
from example3
;
quit;
/*單變量多觀測變一宏變量*/
proc sql;
select group into :_3term separated by " "
from example3
;
quit;
proc sql;
/* create table macros as*/
select *
from dictionary.macros
;
quit;
- 說明
- 這種情況%let的實現(xiàn)一樣要借助于宏,并且因為涉及到了數(shù)據(jù)集層面的操作最爬,%let就更加不太擅長了涉馁;
- 同時,call symput的實現(xiàn)也不太容易爱致,SAS data步長于變量操作弱于觀測操作的弊端便體現(xiàn)出來了烤送。
- 在這種情況下,proc sql的批量化和觀測層面操作的優(yōu)勢便體現(xiàn)出來了糠悯,如果是有多變量多觀測賦值多宏變量的情況帮坚,那proc sql的優(yōu)勢就會更加明顯了;
proc sql給宏變量賦值的情況大致可以分為如下幾種情況
-
單變量單個觀測值賦值給單個宏變量:
proc sql; select var into :mvar from dtin ; quit;
互艾,這種情況用proc sql
不具有優(yōu)勢试和;
-
多變量單觀測值賦值給多個宏變量:
proc sql; select var1, var2, var3, var4 into :mvar1, mvar2, mvar3, mvar4 from dtin ; quit;
-
單變量多觀測賦值給多個宏變量:
proc sql; select var1into :mvar1 -:mvar99 from dtin ; quit;
,其中,mvar99
中的數(shù)值設(shè)置的較大值纫普,是在未知觀測值數(shù)量時的簡便做法阅悍;
-
單變量多觀測賦值給單個宏變量:
proc sql; select var1into :mvar separated by "sep" from dtin ; quit;
,其中,sep
是分隔符昨稼;
-
多變量多觀測值賦值給多個宏變量:
proc sql; select var1, var2, var3, var4 into :var1m1 -:var1m99, var2m1 -:var2m99, var3m1 -:var3m99, var4m1 -:var4m99 from dtin ; quit;
溉箕,其中的4個變量均有多個觀測值;
- 舉例
proc sql;
select name, weight, height into :name1 -:name99,
:weight1 -:weight99,
:height1 -: height99
from sashelp.class(where = (sex = "女"))
;
quit;
-
多變量多觀測值賦值給多個宏變量悦昵,但變量內(nèi)觀測值拼接:
proc sql; select var1, var2, var3, var4 into :var1m1 -:var1m99, var2m1 -:var2m99, var3m1 -:var3m99, var4m1 -:var4m99 from dtin ; quit;
肴茄,其中的4個變量均有多個觀測值;
proc sql;
select name, weight, height into :name separated by " ", :weight separated by " " ,:height separated by " "
from sashelp.class(where = (sex = "女"))
;
quit;
總結(jié)
不涉及數(shù)據(jù)集的單變量的宏變量賦值但指,%let很實用寡痰;
基于數(shù)據(jù)集且多在變量層面操作抗楔,call symput和proc sql均適用;
基于數(shù)據(jù)集且涉及多個變量和觀測層面的操作拦坠,proc sql比較有優(yōu)勢连躏,其他兩種實現(xiàn)起來就需要更多的代碼量;