首页 > 解决方案 > Sas 过滤器宏

问题描述

嗨,我有一个宏,它设计为只接受一个过滤器值,但是我想让它成为多个输入逗号分隔值代码。请帮忙。data new (where name =John, David, Ralph)

标签: sas

解决方案


正确的where=选择是

data new (where=(name in ('John', 'David', 'Ralph'));

你准备好给你的宏传递一个逗号分隔的引用值列表了吗?

当前的宏是什么样的?

假设宏接受一个不带引号的值:

%macro my_macro (name);
  data new (where=(name="&name"));
    set sashelp.class;
  run;
%mend;

%my_macro (Alfred)

更改后的宏,接受引用的值列表将需要%STR('value-1', ..., 'value-n' )在宏调用中以屏蔽逗号。未屏蔽时,每个值都将被视为一个单独的参数。

%macro my_macro (names);
  data new (where=(name in (&names)));
    set sashelp.class;
  run;
%mend;

%my_macro (%str('Alfred', 'Jane'))

SAS in 运算符允许值列表以空格分隔,因此此调用也可以工作。

%my_macro ('Alfred'  'Jane')

如果您希望在传递名称值时不加引号,则必须进行更多编码。这些PARMBUFF %macro选项将让您的代码访问一个自动变量syspbuff,该变量是宏名称之后的所有内容。

所以调用

%my_macro (Alfred, Jane, Authur)

syspbuff导致

(Alfred, Jane, Authur)

请参阅文档%MACRO 宏语句 - 示例 #3,它显示了%DO循环如何%SCAN()用于解析SYSPBUFF

在进入那个兔子洞之前,问问自己“如果过滤器值本身需要包含逗号怎么办”?未引用值的“简单”合约突然变得令人头疼。被调用者需要用%str

%my_macro (Alfred,William,Wayne%str(,)Bruce,%str(Grayson, Dick))

翻转问题,您可以传递匹配任何这些值的分隔列表,然后使用诸如FINDW检查匹配的函数

%macro my_macro (names);
  data new (where=(FINDW("&names",trim(name),'|')));
    set sashelp.class;
  run;
%mend;

%my_macro (Alfred|Jane)

推荐阅读