[SAS] macro 反覆運算%DO part1

在Macro巨集的世界裡面,同樣也有Do Loop迴圈的使用

有單純的%DO、也有條件式的設定%DO %UNTIL、或是%DO %WHILE

正如同字面上的意思去進行反覆運算(iterative processing)

因此本篇記錄關於在macro程式中,如何使用%DO進行反覆運算

既然是反覆運算,反覆「幾次」就是一個重要的關鍵值,比如說我要這個迴圈重複做3次

這個3,就是重要的keyword,進一步使用者就要定義起始到結束的值,比方說從2000反覆運算到2005

2000就是起始值、2005就是結束值

因此一個%DO迴圈的架構長這樣↓

%DO  macro變數 =起始值   %TO   結束值   <%BY 增加量>;
     其他macro statement
%END;

這框架與我們在Data step內寫的迴圈非常類似,%BY依照需求可撰寫也可不寫

老樣子,碰到DO就要給他配一個END作結束,好包夾在一起。

注意:%DO迴圈中的macro變數前面不可以有&記號,但是之後引用的話就要加上&記號

下面將使用參考書中的簡化範例來說明

範例:使用者手上有三筆資料sales.year2005,sales.year2006,sales.year2007,,分別代表2005~2007的業務資料

現在想針對這三筆資料進行基本統計量計算,在此基本統計量使用proc means操作,因此我們將使用%DO來撰寫程式

%macro multrep(startyear,stopyear);/*這裡下了兩個參數startyear,stopyear*/
     %do yrvalue=&startyear %to &stopyear;/*給定起始值與結束值,記得yrvalue前面不給&*/
            proc means data=sales.year&yrvalue;/*會改變的就是資料檔末尾的年份數字&yrvalue*/
                 class section;
                 var cose listprice;
            run;
     %end;
%mend multrep;

%multrep(2005,2007)/*呼叫打好的macro程式multrep,給定參數值*/

在macro processor運作之後,將值帶入引用的地方,會解讀成…(注意粗體字)

  proc means data=sales.year2005;
       class section;
       var cose listprice;
  run;

  proc means data=sales.year2006;
       class section;
       var cose listprice;
  run;

  proc means data=sales.year2007;
       class section;
       var cose listprice;
  run;

在程式都沒有錯誤的前提下,SAS會自動跑完這三筆資料的proc means。

但是%DO不僅僅只有這樣而已

如何在SAS statement裡面建立一個%DO迴圈將是下一篇macro記錄的重點

歡迎大家補充或建議讓文章更加完善~

—-

參考資料:SAS Macro Programming Made Easy, Second Edition

Share


4 Responses to “[SAS] macro 反覆運算%DO part1”

  1.   Carl Zhou Says:

    再次打擾了,我想用宏實現一下過程:
    data abc1-abc3;
    input s @@;
    cards;
    1 2 3 4 5
    ;
    run;

    於是乎我這麼寫:

    %macro createdata (name, number);
    %do n=1 %to &number;
    &name.&n.;
    %end;
    %mend createdata;

    data %createdata(abc,3);
    input s @@;
    cards;
    1 2 3 4 5
    ;
    run;

    但是出現錯誤,日誌如下:

    997 %macro createdata (name, number);
    998 %do n=1 %to &number;
    999 &name.&n.;
    1000 %end;
    1001 %mend createdata;
    1002
    1003 data %createdata(abc,3);
    NOTE: 由巨集變數“N”生成行。
    1 abc2
    —-
    180
    NOTE: 由巨集變數“N”生成行。
    1 abc3
    —-
    180
    ERROR 180-322: 語句無效或未按正確順序使用。

    1004 input s @@;
    1005 cards;

    NOTE: SAS 系統由於錯誤而停止了該步的處理。
    WARNING: 資料集 WORK.ABC1 可能不完整。該步停止時,共有 0 個觀測和 1 個變數。
    WARNING: 資料集 WORK.ABC1 由於該步已停止,而沒有被替換。
    NOTE: “DATA 語句”所用時間(總處理時間):
    實際時間 0.16 秒
    CPU 時間 0.12 秒

    1007 ;

    1008 run;

    請問我哪裡錯了呢 或者如何才能用宏來實現 data 數據集的批量生成并動態命名呢
    謝謝

  2.   Carl Zhou Says:

    哦哦 – 我發現了 真是分號的錯誤 – 不好意思哈 -

  3.   Shrimp Li Says:

    恭喜~

  4.   Carl Zhou Says:

    謝謝~ 哈哈~

留言回覆

CAPTCHA 驗證圖片 CAPTCHA Audio
更換一張圖片

Since 2010 total of 463303 visits