SAS根据条件生成表?

SAS根据条件生成表?,sas,conditional-statements,sas-macro,proc-sql,Sas,Conditional Statements,Sas Macro,Proc Sql,我正在尝试编写一个宏,它将根据某些条件创建一个新表。用户可以输入单个数字或一系列数字来过滤原始数据 例如,如果起始数据集如下所示,最终用户可以选择按单个数字(即:其中Z=1)或一系列数字(即:其中Z介于1和5之间)过滤列Z 如果用户希望输入一个要筛选的数字范围,则将填充&start\u range和&end\u range的值。如果用户希望筛选单个数字,&end_range将等于null 我需要检查&end_range是否等于null的代码。如果是,where语句应该为列Z=&start\u r

我正在尝试编写一个宏,它将根据某些条件创建一个新表。用户可以输入单个数字或一系列数字来过滤原始数据

例如,如果起始数据集如下所示,最终用户可以选择按单个数字(即:其中Z=1)或一系列数字(即:其中Z介于1和5之间)过滤列Z

如果用户希望输入一个要筛选的数字范围,则将填充&start\u range和&end\u range的值。如果用户希望筛选单个数字,&end_range将等于null

我需要检查&end_range是否等于null的代码。如果是,where语句应该为列Z=&start\u range中的所有行创建一个新表。如果&end_range不等于null(它填充了一个值),where语句将为Z列位于&start_range和&end_range之间的所有行创建一个新表

对于单个值,(其中&start_range=1和&end_range=''),结果表为:

X    Y    Z
2     1   1
X    Y    Z
0    1    3
2     1   1
对于一个值范围,(其中&start_range=1和&end_range=5),结果表为:

X    Y    Z
2     1   1
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();

与创建宏定义不同,我建议通过为起始和结束范围创建两个简单的宏变量来解决问题。起始范围总是有一个有效的数字,但对于结束范围,您可以在逻辑中进行编码,以在结束范围值为空/空的情况下获取开始范围值。检查下面的代码,让我知道它是否有帮助

data raw_data;
infile datalines missover;
input X    Y    Z;
datalines4;
0    1    3
2    7    9
0     0   0
2     1   1
;;;;
run;
/*User enters the range*/
%let start_range=1;
%let end_range=5;

/*User entered data refining*/
%let end_range=%sysfunc(coalescec(&end_range,&start_range));

proc sql;
create table filtered_data AS
select *
from raw_data
where z between &start_range and &end_range
;
quit;
proc print data=filtered_data;run;
如果仍然希望创建宏定义来解决问题,请尝试调整宏定义中的第一个%If语句,并删除在PROC SQL的WHERE语句中应用于宏变量的单引号。查看更新的宏定义

%macro filter;
proc sql;   
            create table filtered_data AS
            select raw_data.* 
            from raw_data
            WHERE       
                  %if %length(&end_range) %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子句传递给宏。只有当您要生成对宏的动态调用并且不知道参数的值是什么时,此练习才真正有价值。