2016-03-08 94 views
0
%macro nextNB(ds); 
%local dsid nv rc; 
%let dsid = %sysfunc(open(&ds)); 
%let nv = %sysfunc(smallest(2, &dsid)); 
%let rc =%sysfunc(close(&dsid)); 
&nv 
%mend nextNB; 

%put %nextNB(WORK.TEST); 

& dsid返回值爲5,7和9的數據集。如何更改我的宏函數,使其返回第二小的值7?SAS宏 - 陣列

+0

你想做什麼?如果你已經有數據集中的數據,爲什麼要用宏代碼來分析它? – Tom

+0

因爲最終,我將用該宏內的查詢替換數據集。 –

+0

如果用查詢替換數據集,那麼宏將需要生成SAS代碼。所以你不能再創建一個返回值的函數式宏。 – Tom

回答

0

要做到這一點作爲一個宏功能,你需要閱讀整個數據集。我不確定SMALLEST()函數是否可以正常工作。你想怎麼處理關係?這是一個找到第二小值並忽略重複值的程序。

%macro nextNB(ds,var); 
%local dsid rc minv nv &var ; 
%*---------------------------------------------------------------------- 
Open the dataset and link dataset variables to macro variables. 
Loop until all observations are read. 
-----------------------------------------------------------------------; 
%let minv=.; 
%let nv=.; 
%let did=%sysfunc(open(&ds(keep=&var))); 
%syscall set(did); 
%do %while(not %sysfunc(fetch(&did))); 
    %if %sysevalf(. = &minv) %then %let minv=&&&var; 
    %else %if %sysevalf(&&&var <= &minv) %then %let minv=&&&var; 
    %else %if %sysevalf(. = &nv) %then %let nv=&&&var; 
    %else %if %sysevalf(&&&var < &nv) %then %let nv=&&&var; 
%end; 
%let rc=%sysfunc(close(&did)); 
&nv. 
%mend nextnb; 


data list; 
do value= 5,9,5,7,8 ; output; end; 
run; 
%put %nextnb(list,value); 

這將導致找到7作爲第二小的值。

如果您寧願返回5,因爲數據中有兩個5,那麼請將<=更改爲<

1

如果您只想使用現有數據集並將K th值放入宏變量中,那麼只需使用數據步驟即可。

讓我們模擬將數據集名稱,變量名稱,整數和目標宏變量名作爲宏變量傳遞。

%let ds=list ; 
%let var=value ; 
%let k=2 ; 
%let target=new_mv ; 

然後你的數據步驟就是這樣。

data _null_; 
    set &list firstobs=&k obs=&k ; 
    call symputx("&target",&var); 
run; 

如果它沒有排序,那麼也許你可以先排序?

proc sort data=&ds nodupkey ; 
    by &var; 
run; 
+0

我真的很喜歡這個建議,並在本週結束前嘗試並會讓你知道。非常感謝您花時間。 –