SAS學(xué)習(xí)筆記 宏變量賦值

SAS給宏變量賦值大體來(lái)說(shuō)其實(shí)就3種方式:%let語(yǔ)句、data步中的call symput語(yǔ)句proc sql過(guò)程中into語(yǔ)句。
這里根據(jù)變量和觀(guān)測(cè)的數(shù)量分情況進(jìn)行如下討論,即:

  • 單變量單觀(guān)測(cè)變單宏變量
  • 單變量單觀(guān)測(cè)變多宏變量
  • 單變量多觀(guān)測(cè)變多宏變量

單變量單觀(guān)測(cè)變單宏變量

提出問(wèn)題如下:

/*problem1:將組名信息賦值給宏變量group,各組之間\分割,單變量一觀(guān)測(cè)變一宏變量*/

數(shù)據(jù)集如下:

data example1;
    group  = "太極組\圍棋組\古箏組\書(shū)法組";
run;
example1數(shù)據(jù)集

分別使用如下3種方法進(jìn)行宏變量賦值:

/*method1: let statement*/

%let group1 = 太極組\圍棋組\古箏組\書(shū)法組;

%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.;
日志信息

  • 說(shuō)明
proc sql;
/*    create table macros as*/
    select *
    from dictionary.macros
    ;
quit;

上述語(yǔ)句是獲得環(huán)境中macros變量信息的語(yǔ)句,很實(shí)用。

在單變量賦值單宏變量時(shí),%let語(yǔ)句相比其他兩種要簡(jiǎn)單,不必基于數(shù)據(jù)集;而proc sql語(yǔ)句則必須基于數(shù)據(jù)集中的變量產(chǎn)生;call symput則均可以實(shí)現(xiàn)。


單變量單觀(guān)測(cè)變多宏變量

  • 問(wèn)題
/*problem2:將組名信息分別依次賦值給宏變量term1,term2,...,單變量一觀(guān)測(cè)變多宏變量*/
  • 數(shù)據(jù)集如下:
data example2;
    group  = "太極組\圍棋組\古箏組\書(shū)法組";
run;
xample2數(shù)據(jù)集

分別使用如下3種方法進(jìn)行宏變量賦值:

/*method1: let statement*/
%let term1_1 = 太極組;
%let term1_2 = 圍棋組;
%let term1_3 = 古箏組;
%let term1_4 = 書(shū)法組;

%macro batch;
%do i = 1 %to 4;
    %let _term1_&i. = %qscan("太極組\圍棋組\古箏組\書(shū)法組" , &i. , "\");
%end;

proc sql;
/*    create table macros as*/
    select *
    from dictionary.macros
    where scope = "BATCH"
    ;
quit;
%mend;
%batch;
batch宏批量處理后打印結(jié)果

/*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;
打印結(jié)果

/*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;
打印結(jié)果

  • 說(shuō)明
  1. 這種情況就可以看出 %let語(yǔ)句的劣勢(shì)了,無(wú)法批量操作,為了批量操作我寫(xiě)了個(gè)簡(jiǎn)單宏才實(shí)現(xiàn);
  2. call symput語(yǔ)句的實(shí)現(xiàn)則很簡(jiǎn)單,這是因?yàn)橹簧婕暗絾蝹€(gè)變量的操作,是data步的優(yōu)勢(shì)所在,代碼量很少;
  3. proc sql給宏變量賦值的優(yōu)勢(shì)在這里體現(xiàn)的不明顯,但是也可以看出它針對(duì)數(shù)據(jù)集層面,批量化宏變量賦值操作的便捷性。

單變量多觀(guān)測(cè)變多宏變量

  • 問(wèn)題
/*problem3:將分組變量中組名觀(guān)測(cè)依次賦值給宏變量term1,term2,...,單變量多觀(guān)測(cè)變多宏變量*/
  • 數(shù)據(jù)集
data example3;
    length group $200.;
    input group;
cards;
太極組
圍棋組
古箏組
書(shū)法組
;
proc print;
run;

example3打印結(jié)果

  • 使用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;
_out3輸出
復(fù)制后宏變量結(jié)果輸出

使用%let解決這個(gè)問(wèn)題,需要先轉(zhuǎn)置,使問(wèn)題變?yōu)榛谧兞浚簿褪橇?,彌補(bǔ)基礎(chǔ)語(yǔ)句基于觀(guān)測(cè)處理問(wèn)題能力偏弱的短板
然后構(gòu)建宏,在宏里還要再把數(shù)據(jù)集里的多個(gè)變量賦值為單個(gè)宏變量,這是因?yàn)?strong>%let是在變量層面解決問(wèn)題的,數(shù)據(jù)集無(wú)處下爪;
之后使用循環(huán),彌補(bǔ)%let批量處理問(wèn)題的短板。


/*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;
打印結(jié)果
  • 說(shuō)明

可以看到,使用call symput解決這個(gè)問(wèn)題,同樣需要經(jīng)歷轉(zhuǎn)置步驟轉(zhuǎn)變?yōu)樘幚碜兞康膯?wèn)題;然后在data步使用數(shù)組循環(huán),還是比較繁瑣的。

  • proc sql的優(yōu)勢(shì)就體現(xiàn)出來(lái)了,一個(gè)代碼塊就達(dá)成目的,如下:

/*method3:proc sql statement*/
/*單變量多觀(guān)測(cè)變多個(gè)宏變量*/
proc sql;
     select  group  into :_3term1 -: _3term99
     from example3
     ;
quit;

/*單變量多觀(guān)測(cè)變一宏變量*/
proc sql;
     select  group  into :_3term separated by " "
     from example3
     ;
quit;

proc sql;
/*    create table macros as*/
    select *
    from dictionary.macros
    ;
quit;
打印結(jié)果

  • 說(shuō)明
  1. 這種情況%let的實(shí)現(xiàn)一樣要借助于宏,并且因?yàn)樯婕暗搅藬?shù)據(jù)集層面的操作,%let就更加不太擅長(zhǎng)了;
  2. 同時(shí),call symput的實(shí)現(xiàn)也不太容易,SAS data長(zhǎng)于變量操作弱于觀(guān)測(cè)操作的弊端便體現(xiàn)出來(lái)了。
  3. 在這種情況下,proc sql的批量化和觀(guān)測(cè)層面操作的優(yōu)勢(shì)便體現(xiàn)出來(lái)了,如果是有多變量多觀(guān)測(cè)賦值多宏變量的情況,那proc sql的優(yōu)勢(shì)就會(huì)更加明顯了;

proc sql給宏變量賦值的情況大致可以分為如下幾種情況

  1. 單變量單個(gè)觀(guān)測(cè)值賦值給單個(gè)宏變量:proc sql; select var into :mvar from dtin ; quit;,這種情況用proc sql不具有優(yōu)勢(shì);

  1. 多變量單觀(guān)測(cè)值賦值給多個(gè)宏變量:proc sql; select var1, var2, var3, var4 into :mvar1, mvar2, mvar3, mvar4 from dtin ; quit;

  1. 單變量多觀(guān)測(cè)賦值給多個(gè)宏變量:proc sql; select var1into :mvar1 -:mvar99 from dtin ; quit;,其中,mvar99中的數(shù)值設(shè)置的較大值,是在未知觀(guān)測(cè)值數(shù)量時(shí)的簡(jiǎn)便做法;

  1. 單變量多觀(guān)測(cè)賦值給單個(gè)宏變量:proc sql; select var1into :mvar separated by "sep" from dtin ; quit;,其中,sep是分隔符;

  1. 多變量多觀(guān)測(cè)值賦值給多個(gè)宏變量:proc sql; select var1, var2, var3, var4 into :var1m1 -:var1m99, var2m1 -:var2m99, var3m1 -:var3m99, var4m1 -:var4m99 from dtin ; quit;,其中的4個(gè)變量均有多個(gè)觀(guān)測(cè)值;
  • 舉例
proc sql;
    select name, weight, height into :name1 -:name99,
     :weight1 -:weight99, 
     :height1 -: height99
    from sashelp.class(where = (sex = "女"))
    ;
quit;
情況5 結(jié)果輸出

  1. 多變量多觀(guān)測(cè)值賦值給多個(gè)宏變量,但變量?jī)?nèi)觀(guān)測(cè)值拼接:proc sql; select var1, var2, var3, var4 into :var1m1 -:var1m99, var2m1 -:var2m99, var3m1 -:var3m99, var4m1 -:var4m99 from dtin ; quit;,其中的4個(gè)變量均有多個(gè)觀(guān)測(cè)值;
proc sql;
    select name, weight, height into :name separated by " ", :weight separated by " " ,:height separated by " "
    from sashelp.class(where = (sex = "女"))
    ;
quit;
情況6 舉例輸出

總結(jié)

不涉及數(shù)據(jù)集的單變量的宏變量賦值,%let很實(shí)用;
基于數(shù)據(jù)集且多在變量層面操作,call symputproc sql均適用;
基于數(shù)據(jù)集且涉及多個(gè)變量和觀(guān)測(cè)層面的操作,proc sql比較有優(yōu)勢(shì),其他兩種實(shí)現(xiàn)起來(lái)就需要更多的代碼量;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容