【问题标题】:SAS-Generating Table(s) based on conditional?基于条件的 SAS 生成表?
【发布时间】: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


【解决方案1】:

我建议不要创建宏定义,而是通过为您的开始和结束范围创建 2 个简单的宏变量来解决您的问题。开始范围总是有一个有效数字,但对于结束范围,您可以在逻辑中编码以获取开始范围值,以防结束范围值为空白/空。查看下面的代码,如果有帮助请告诉我。

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;

【讨论】:

    猜你喜欢
    • 2020-08-26
    • 2020-12-11
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 2012-02-22
    相关资源
    最近更新 更多