2015-05-07 118 views
5

我想在SAS中創建類似Excel查找函數的東西。基本上,我爲宏變量var1,var2,...設置了值,我想根據ref表找到它們的索引號。但是我在數據步驟中收到以下消息。在sas中的%let語句後,宏變量未初始化

NOTE: Variable A is uninitialized. 
NOTE: Variable B is uninitialized. 
NOTE: Variable NULL is uninitialized. 

當我打印變量&num1&num2,我什麼也沒得到。這是我的代碼。

data ref; 
    input index varname $; 
    datalines; 
0 NULL 
1 A 
2 B 
3 C 
; 
run; 

%let var1=A; 
%let var2=B; 
%let var3=NULL; 

data temp; 
    set ref; 
    if varname=&var1 then call symput('num1',trim(left(index))); 
    if varname=&var2 then call symput('num2',trim(left(index))); 
    if varname=&var3 then call symput('num3',trim(left(index))); 
run; 

%put &num1; 
%put &num2; 
%put &num3; 

我能得到正確的值&num1&num2,..如果我在if-then語句類型varname='A'。如果我隨後將聲明更改回varname=&var1,我仍然可以獲得所需的輸出。但爲什麼這樣呢?我不想輸入實際的字符串值,然後將其更改回宏變量以獲得每次結果。

+1

我建議你做一個搜索在http://www.lexjansen.com/上進行「查找」,找到有關在SAS中執行此類事情的許多不同方法的SAS論文。 – DWal

回答

8

解決眼前的問題

你需要用雙引號中的宏觀變量,如果你想SAS將它們視爲字符串常量。否則,它將以與在數據步驟中找到的任何其他文本隨機位相同的方式對待它們。

或者,您可以重新定義宏變量以包含引號。

作爲進一步的選項,您可以使用symgetresolve函數,但通常不需要這些函數,除非您想創建宏變量並在同一數據步驟中再次使用它。如果將它們用作雙引號的替代品,則它們傾向於使用更多的CPU,因爲它們會默認每行評估一次宏變量 - 通常,在代碼執行之前,在編譯時僅對宏變量進行一次評估。

更好的方法?

對於你正在做的查找,你實際上根本不需要使用數據集 - 你可以定義一個自定義格式,這使得你可以更靈活地使用它。例如。這將創建一個名爲lookup格式:

proc format; 
    value lookup 
    1 = 'A' 
    2 = 'B' 
    3 = 'C' 
    other = '#N/A' /*Since this is what vlookup would do :) */ 
    ; 
run; 

然後你可以使用的格式,像這樣:

%let testvar = 1; 
%let testvar_lookup = %sysfunc(putn(&testvar, lookup.)); 

或數據的步驟:

data _null_; 
    var1 = 1; 
    format var1 lookup.; 
    put var1=; 
run; 
+0

我明白了。感謝您介紹替代品! – Yimai

+2

很好的答案。您也可能想要解釋如何從這裏的數據集創建格式(因爲用戶可能已經在數據集中進行了此查找)。 – Joe