2013-12-16 80 views
0

我正在參加SAS課程,並有一個項目可以完成。當然,我並不是在尋找確切的答案(儘管那樣會很好),但是我們真的很感激正確的方向。使用SAS Macro創建間隔

問題是編寫一個宏,該宏創建年齡從一個人年齡的年齡組。給出的代碼是:

data a ; 
    infile in1 ; 
    input name $ age ; 

    if 30 le age < 33 then agegrp = 30 ; 
    else if 33 le age < 36 then agegrp = 33 ; 
    else if 36 le age < 39 then agegrp = 36 ; 
    else if 39 le age < 42 then agegrp = 39 ; 
    else if 42 le age < 45 then agegrp = 42 ; 
    else if 45 le age < 48 then agegrp = 45 ; 
    else if 48 le age < 51 then agegrp = 48 ; 
    else if 51 le age < 54 then agegrp = 51 ; 
    else if 54 le age < 57 then agegrp = 54 ; 
    else if 57 le age then agegrp = 57 ; 

我的工作是編寫一個生成這些if-then/else語句的SAS宏。這是我到目前爲止。我意識到這不會運行,但我想要弄清楚一些事情,告訴你們這些任務有多遠。

options ls=78 formdlim=' ' ; 

%MACRO CODEIT(start= , stop= , count= , old= , new=); 
%let x=&start; 
%let y=%eval(&start+&count); 

if &start 
    %do x=&start+&count %to &stop %by &count ; 
     <= &old < &x then &new=&start ; 
     %let start=&x ; 
     else if &start 
    %end ; 
<= &old then &new=&start ; 

%MEND 

data a ; 
    input age ; 
    datalines; 
    30 31 32 33 34 37 
    38 39 39 41 42 45 
    46 46 47 49 50 50 
    52 53 54 55 56 57 

%CODEIT(start=30, stop=57, count=3, old=0, new=0); 

我非常感謝你提前給你提供的所有幫助。

+0

是否需要成爲宏?這通常不是實現這一目標的最佳實踐。 – Joe

+0

它需要是一個宏。該宏應該能夠獲取人們年齡的數據集,並根據數據中的年齡範圍生成不同範圍的if-then/else語句。非常感謝您的快速回復。 – William

+1

我希望這位教授至少在「這是可怕的編程習慣,但是我爲了學習的目的而要求你這麼做」之前寫過? :) – Joe

回答

1

你有一些小問題,但(根據具體要求)通常會有這個問題。

首先,宏需要在數據步驟內執行。然而,你有datalines,這意味着這將無法正常運行 - datalines必須是數據步驟的最後一部分。

data a; 
input age; 
<%codeit call> 
datalines; 
<data> 
;;;; 
run; 

其次,你的%do控件有點不對。你實際上可以通過兩種方式來做到你理論上可以使用%do,但實際上你應該使用do。我也會改變開始/結束的工作方式,但這只是個人偏好(我會讓start不是最低值,而是最低範圍的起點;而end應該是最高範圍的結束點,因爲這對我來說是最合乎邏輯的意義)。

do _iter = &start to &stop by &count; 
    if _iter. le &old. lt _iter+&count. then &new. = &start.; 
end; 
if &old. lt &start. then &new.=&start.-&count.; 
else if &old. ge &end then &new. = &old.+&count.; 

這應該是你的宏。

現在,這就是說,沒有理由爲此使用宏;你可以在數據步驟中完成所有這些工作。如果這是一個宏類,那麼你可以在%do中製作大致相同的代碼;您仍然想要將整個if包裝在%do中(您可以使用&_iter.或任何用於迭代變量的值)。

在現實生活場景中,您可以使用沒有宏變量(僅硬編碼)的張貼循環,也可以更有效地使用select語句;或者甚至更好地使用格式(proc format)來實現重新編碼。格式確實是最好的選擇,因爲這正是他們所做的,而且他們可以在不需要新的datastep的情況下完成。