2013-10-10 38 views
1

我正在想創建這樣的數據集,P1_31,P1_32,P1_36,P1_37在SAS使用下面的代碼%DO循環顯示我的錯誤是SAS

%MACRO P_MISS1; 
%LET T1= 3 ; 
%LET H1=1; 
%DO %WHILE(&H1<=1); 
     %LET TR1=%SCAN(&T1,&H1); 
      %DO I= 1,2,6 %TO 7; 
       DATA P1_&TR1&I; 
        VALUE=.; 
        COL&TR1=.; 
       RUN; 
       OUTPUT; 
      %END; 
    %LET H1=%EVAL(&H1+1); 
%END; 
%MEND P_MISS1; 

%P_MISS1 

我用很多宏觀的計劃,所有上述數據集,但只是爲了減少我創建下面的代碼的代碼大小。我知道我正在做%Do Loop的問題。如果有可能使用上面的代碼,請引導我使用代碼。

+0

使用%前做我= 1, 2,6%到7,我用%做我= 1,2,6,7。 –

+0

我不認爲宏語言支持任何結構。 (兩者都是數據步驟中的合法結構,但使用它的人會很奇怪,因爲它沒有做任何事情。)我相信宏語言只支持%do x%到y,沒有逗號列表或類似的東西。 – Joe

回答

3

編寫這種代碼的更好的方式就像編寫代碼任何一樣,就是把宏寫成想要多次運行的代碼,然後多次調用它。這使得它更加可重用,更清晰地表明你正在做什麼,並最終以更短的代碼結束。

這個特定的代碼集並不是完全明顯的,如何編寫它的最好方法是,因爲驅動你輸入的東西並不明顯。但是,這樣的事情是有道理的。

%macro make_ds(tr,i); 
DATA P1_&TR1&I; 
    VALUE=.; 
    COL&TR1=.; 
RUN; 
%mend make_ds; 

%macro call_make_ds(tr); 
    %make_ds(&tr,1); 
    %make_ds(&tr,2); 
    %make_ds(&tr,6); 
    %make_ds(&tr,7); 
%mend call_make_ds; 

對於四個項目我只是寫出來,如果沒有數據集或其他實體包含四個項目。編寫複雜循環的代碼很簡單,容易出錯,維護起來也不容易。如果您有一個包含i的可能值的數據集,則使用該數據集調用%make_ds宏。

然後根據適當的參數調用該宏。例如,如果TR可以從一個數據集來決定(假設你有一個包含所有TR值要遍歷數據集),你可以做這樣的事情:

proc sql; 
select distinct cats('%call_make_ds(',trval,')') into :makelist 
separated by ' ' 
from your_ds; 
quit; 
&makelist; 
+0

感謝您的編程思想。但我可以使用do循環以便我可以創建這些數據集與應用最小的代碼,基本上我需要創建大量的數據集:P1_31,P1_32,P1_36,P1_37 P1_22,P1_23,P1_24, P1_26,P1_27 –

+0

再次閱讀答案?我想我清楚地回答了。如果您不清楚某些事情,請澄清您需要幫助的內容。 – Joe

1

那麼,這條線是錯誤的,只要我的SAS知識雲:

%DO I= 1,2,6 %TO 7; 

通常情況下,你寫的:

%do macrovar=startvalue %to endvalue; 

我建議你創建一個宏與項目名單你想使用後綴和循環他們:

%MACRO P_MISS1; 
    %let suffixes=31 32 36 37; 
    %let elementNbr=1; 
    %let elementValue=%scan(&suffixes.,&elementNbr.); /*initiate with first element*/ 

    %do %while(&elementValue. NE %str()); /*as long as we find elements, we continue iterating*/ 
     data P1_&elementValue.; 
      value=.; 
      col3=.; 
      output; 
     run; 
     %let elementNbr=%eval(&elementNbr.+1); /*increase elementNbr, so that we look now for the next item in our list*/ 
     %let elementValue=%scan(&suffixes.,&elementNbr.); /*initiate next element*/ 
    %end; 
%mend; 
%P_MISS1 

你似乎有一些事情與2級:mult 10個單位和10個單位。我在上面的代碼中跳過了這個細微差別,但是可以通過嵌套這樣的循環來實現它。
例如,外層循環的倍數爲10(在你的情況下,它只是第30層中的3層)和內層循環遍歷你想要的值(在你的情況下:1,2,6和7)

所有的說法,我似乎錯過了你的代碼點。您正在創建空數據集,但是目的是什麼?你確定你需要在你的場景中有這些嗎?

+1

此代碼將循環不休。您需要額外的%let elementValue =%scan(&suffixes。,&elementNbr。);在做結束之前避免它。 –

+0

謝謝你指出。糾正它。 – mvherweg

+0

是的,我需要這些空數據集與具有P值的同一系列的其他數據集連接。 –