假设我喜欢执行以下操作(使用示例变量名称以获得更好的可读性):
获取参数InParameter
并将其与数据集MyVar1
中的变量MyData
相匹配
返回已过滤观察的变量MyVar2
的所有值
来自子程序/功能
我可以在proc sql / datastep里面使用
这是我到目前为止所得到的(显然不起作用):
proc fcmp outlib=work.funcs.MyFunction;
function MyFunction(InParameter $);
array MyArray ... ; /* Here: Create an array with something like SELECT MyVar2 FROM MyData WHERE MyVar1 = Inparameter */
return(MyArray{});
endsub;
;
quit;
options cmplib=work.funcs;
data MyOutput;
set Somedata;
if MyVar2 in MyFunction("H20") then output;
run;
简而言之:
感谢您的帮助!
答案 0 :(得分:1)
不确定某个函数是否可以与IN
运算符一起使用。您可能需要使用宏包装函数调用以生成正确的语法。在这种情况下,为什么不只是开始一个宏?
这是用于从数据集中的变量中提取值的通用宏。
%macro varlist
/*----------------------------------------------------------------------
Generate list of values from dataset
----------------------------------------------------------------------*/
(dataset /* Input dataset */
,variable /* Variable Name */
,quote=1 /* Add quotes around values? 1=Single 2=Double */
,comma=1 /* Add comma between values? */
,paren=1 /* Add parentheses around results? */
);
%local did sep &variable ;
%if &paren=1 %then (;
%let did=%sysfunc(open(&dataset));
%syscall set(did);
%do %while(0=%sysfunc(fetch(&did)));
%let &variable=%qsysfunc(trim(%superq(&variable)));
%if "e=1 %then &sep.%sysfunc(quote(&&&variable,%str(%')));
%else %if "e=2 %then &sep.%sysfunc(quote(&&&variable));
%else &sep.&&&variable;
%if &comma=1 %then %let sep=,;
%end;
%let did=%sysfunc(close(&did));
%if &paren=1 %then );
%mend varlist;
示例电话:
%put %varlist(sashelp.class,name);
%put %varlist(sashelp.class(where=(sex='M')),age,quote=0,comma=0);
所以在你的情况下你可以像这样使用它:
data MyOutput;
set Somedata;
where MyVar2 in %varlist(Mydata(where=(MyVar1="H20")),MyVar2) ;
run;
答案 1 :(得分:1)
我们创建了一个名为%ds2list()
的实用程序宏,它将执行您想要的过程。它不使用数组语句,但它实现了相同的结果。
宏只是以列表格式返回数据集中的值。以下是调用它的示例:
%put %ds2list(iDs=sashelp.class, iField=name, iQuote=1);
这将返回:
'Alfred','Alice','Barbara','Carol','Henry','James','Jane','Janet','Jeffrey','John','Joyce','Judy','Louise','Mary','Philip','Robert','Ronald','Thomas','William'
%ds2list()
的默认行为是逗号分隔返回的值,但它非常灵活。您可以将分隔符更改为您选择的值(或无分隔符),您可以打开或关闭引号,或将它们从单引号更改为双引号,并且您可以提供通常在{{{ 1}}语句,例如set
语句。
此外,因为宏是纯宏代码,所以您可以在SAS中的任何位置使用它。在你喜欢的任何proc / data / macro中。当我们想要返回一大堆ID时,我们会广泛使用它来调用ODBC直通。
以下是如何使用它的示例。首先创建一个表,其中包含要与列表值进行比较的值:
where=()
迭代我们要根据列表检查的值:
data keep;
input name $;
datalines;
Alfred
Carol
Janet
run;
返回:
data want;
set keep;
if name in (%ds2list(iDs=sashelp.class, iField=name, iQuote=1, iDsOptions=where=(sex='F'))) then do;
output;
end;
run;
您可以看到Alfred被排除在结果之外,因为他被Obs name
=== =====
1 Carol
2 Janet
子句过滤掉了。
这是宏,我建议将它放在你的宏自动调用库中:
where=()
答案 2 :(得分:0)
你最好使用宏。
%macro subset(inParameter, indata, outdata);
proc sql noprint;
create table &outdata as
select * from &indata
where myVar2 in (select distinct myVar2 from myData where myVar1 = "&inParameter);
quit;
%mend;
%subst(H20,Somedata,MyOutput);