2016-11-11 57 views
0

我試圖通過編寫下面SAS代碼,但我得到的是表1.我想不出什麼我錯過了構建表2。非常感謝幫助,謝謝。SAS SymputX和Symget功能

 &counter = 4 

    data new;set set1; 
    total = 0; 
    a = 1; 
    do i = 1 to &counter; 
     call symputX('a',a); 
     total = total + Tem_&a.; 
     a = symget('a')+1; 
     call symputX('a',a); 
    end; 
    run; 



     Table 1 
     ID Amt Tem_1 Tem_2 Tem_3 Tem_4 total 
     4 500 1  4  5 900 3600 
     5 200 50  100  200  0  0 
     9 50 40  0  0  0  0 
     10 500 70  100  250  0  0 



    Table 2 
    ID Amt Tem_1 Tem_2 Tem_3 Tem_4 total 
     4 500 1  4  5 900  910 
     5 200 50  100  200  0  350 
     9 50 40  0  0  0  40 
    10 500 70  100  250  0  420 

回答

2

不幸的是,您不能以這種方式使用SYMPUT和SYMGET。雖然可以使用它們來存儲/檢索宏變量值,但不能在執行後更改發送給編譯器的代碼。

基本上,SAS已經弄清楚了什麼它應該對數據步循環的每次迭代做它看起來在任何數據之前的機器代碼(這被稱爲編譯)。所以,問題是,你不能定義tem_&a.並期望被允許改變什麼_&a.是在執行過程中,因爲它會改變什麼機器代碼需要做的,SAS將不能夠爲充分準備。

因此,你編寫的&a.將在程序編譯時解析,並且在你的數據步驟之前的任何值&a.將被變爲tem_&a.。大概是你第一次運行它時出錯(&a. does not resolve,然後出現一個關於&在變量名中是非法的錯誤),然後最終call symput完成了它的工作,&a在循環結束時得到了一個4,並且永遠更多tem_&a.解析爲tem_4

解決方案?不要爲此使用宏。相反,使用數組。

data new; 
    set set1; 
    total = 0; 
    array tem[&counter.] tem_1-tem_&counter.; 
    a = 1; 
    do i = 1 to &counter; *or do i = 1 to dim(tem); 
     total = total + Tem[i]; 
    end; 
run; 

或者,當然,只是直接將它們相加。

data new; 
    set set1; 
    total = sum(of tem_1-tem_4); 
run; 

如果你真的喜歡宏變量,你當然可以這樣做在宏觀做循環,雖然這是推薦用於此目的,因爲它是真正更好地堅持與數據步技術。但是,無論如何,如果你在宏裏面運行它(這在開放代碼中是無效的),這應該起作用。

data new; 
    set set1; 
    total = 0; 
    %do i = 1 %to &counter; 
     total = total + Tem_&i.;   
    %end; 
    run; 
+0

太感謝你了,喬! –

+0

@Joe可能應該用宏變量引用替換硬編碼的上界或者刪除宏變量引用。現在,如果COUNTER不是4,您將遇到問題。 – Tom

+0

同意@tom,儘管我沒有這樣做的原因是爲了不顯示代碼與原始代碼非常相似以顯示相似之處。 – Joe