2013-03-22 65 views
6

我在尋找一個而的等效爲循環在SAS 9.3宏語言(如在Python或R)。 DO loop似乎是解決方案,但沒有完全按照我的意願工作。 我建立了一個方法,在數據步驟中使用DO循環,但它不適用於宏語言。 例如,在數據的步驟,該代碼工作:「對於」環等效在SAS 9.3

DATA _NULL_; 
    DO i = 1,3,5,9; 
    PUT i; 
    END; 
RUN; 

然後按預期的日誌提示:

1 
3 
5 
9 

當我嘗試做相同的%DO環在宏中,我有一個錯誤。

%MACRO test(); 
    %DO i = 1,2,4,9 ; 
    %PUT i = &i; 
    %END; 
%MEND; 

%test(); 

日誌promp這些消息:

ERROR: Expected %TO not found in %DO statement. 
ERROR: A dummy macro will be compiled 

我在SAS還相當新,計算器,所以我希望我的問題是沒有太愚蠢了。在Python和R中執行此操作非常簡單,然後它必須在SAS中有一個簡單的方法。

感謝的求助 - J.穆勒

回答

6

我曾經遇到過在SAS宏語言這種模式最接近的是這樣的:

%MACRO test(); 

%let j=1; 
%let vals=1 2 4 9; 
%do %while(%scan(&vals,&j) ne); 
    %let i=%scan(&vals, &j); 

    %put &i; 

    %let j=%eval(&j+1); 
%end; 
%MEND; 

%test(); 

(警告:未經檢驗的,因爲我不再有SAS安裝我可以測試了這一點上。)

+0

我試過了,它的工作完美。它不像Python或R語法那麼簡單,但它也適用於字符列表。謝謝! – jomuller 2013-03-22 15:23:38

4

你當然可以避開這樣說:

options mindelimiter=,; 
options minoperator; 
%MACRO test(); 
    %DO i = 1 %to 9 ; 
    %if &i in (1,2,4,9) %then %do; 
    %PUT i = &i; 
    %END; 
    %end; 
%MEND; 

%test(); 

不過,我認爲你通常可以通過執行您的宏多次,而避免這類呼叫比試圖控制宏內部的循環。例如,想象一個數據集和一個宏:

data have; 
input x; 
datalines; 
1 
2 
4 
9 
;;;; 
run; 

%macro test(x); 
%put &x; 
%mend test; 

現在您想爲該列表中的每個值調用%test()一次。好的,容易做到。

proc sql; 
select cats('%test(',x,')') into :testcall separated by ' ' from have; 
quit; 

&testcall; 

這一工程一樣好您的%做循環,但它的數據驅動的,這意味着如果你想改變調用你只需要改變的數據集(或者,如果您的數據發生變化,來電自動改變!) 。一般來說,當設計爲數據驅動編程而不是完全書面代碼時,SAS更有效。

+0

我對數值列表使用了類似的東西,但 – jomuller 2013-03-22 14:50:11

+1

是的,如果你想要做字符列表,你需要像Simon的例子那樣掃描列表。我會注意到,SAS宏語言不完全是一種全功能的語言 - 不要指望它是。大多數事情都可以在基礎SAS內完成,不需要在宏語言中進行嚴肅的編程,而避免重複性代碼。添加到答案的示例。 – Joe 2013-03-22 14:52:19

+0

(我的句子結尾,對不起技術問題)......它不適用於我相信的角色列表。 – jomuller 2013-03-22 14:58:48