【发布时间】:2015-05-04 12:41:01
【问题描述】:
我正在尝试编写一个宏,它将根据某些条件创建一个新表。用户可以输入单个数字或数字范围来过滤原始数据。
例如,如果起始数据集如下所示,最终用户可以选择按单个数字(即:Z=1)或数字范围(即:Z 介于 1 和5)。
X Y Z
0 1 3
2 7 9
0 0 0
2 1 1
如果用户想要输入要过滤的数字范围,则会为 &start_range 和 &end_range 填充值。如果用户想要过滤单个数字,&end_range 将等于 null。
我想要检查 &end_range 是否等于 null 的代码。如果是这样,where 语句应该为列 Z=&start_range 的所有行创建一个新表。如果 &end_range 不等于 null(它填充了一个值),where 语句将为 Z 列介于 &start_range 和 &end_range 之间的所有行创建一个新表。
对于单个值(其中 &start_range=1 和 &end_range=''),结果表将是:
X Y Z
2 1 1
对于一系列值(其中 &start_range=1 和 &end_range=5),结果表将是:
X Y Z
0 1 3
2 1 1
这是我到目前为止的代码,不是 100% 确定语法是否正确,因此欢迎任何和所有建议,谢谢!!:
%macro filter();
proc sql;
create table filtered_data AS
select raw_data.*
from raw_data
WHERE
%if &end_range NE '' %then %do;
Z between '&start_range' AND '&end_range';
%end;
%else %do;
Z = '&start_range';
%end;
quit;
%mend;
%filter();
【问题讨论】:
-
询问特定问题的问题往往比一般故障排除请求更适合本网站上的问答格式。尽管如此,我有两个建议。 (1) 宏的参数可能应该在
%macro语句中列出,并在调用宏时指定。 (2) 不需要重复整个查询;您可以将%if %then %else条件放在where语句中,以仅控制可以更改的代码行。这影响不大,但它让阅读代码的人清楚地知道代码的哪一部分是有条件的。 -
如果宏调用(和参数)要手动编写,那么您可能只想将要使用的 where 子句传递给宏。仅当您要生成对宏的动态调用并且不知道参数的值将是什么时,此练习才真正值得。
标签: sas conditional-statements sas-macro proc-sql