2016-03-08 82 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

我真的很喜欢这个建议,并在本周结束前尝试并会让你知道。非常感谢您花时间。 –