SAS宏使用多个列表作为条件

时间:2016-02-24 14:33:51

标签: sas

我有一个条件表,我想用它来创建我的其他表。现在我希望我的代码通过我的条件表考虑到这两个条件。我的数据如下所示。

 Month    Date1     Date2     Line  
 Jan2010  01Jan2010 31Jan2010 PL  
 Feb2010  01Feb2010 28Feb2010 CB
 Feb2010  01Feb2010 28Feb2010 HB
 Mar2010  01Mar2010 31Mar2010 PL  

当前代码

  %Macro Split_Data(Month,BeginDate,EndDate,Line);  
  Data Want_&Month._&Line.;  
    Set Have;  
    Where Date > &BeginDate and Date <&EndDate and Line = '&Line.';  
  Quit;
  %Mend;  
  %Split_Data(Jan2010,'01JAN2010'd,'31JAN2010'd,PL);  
  %Split_Data(Jan2010,'01JAN2010'd,'31JAN2010'd,CB);  

我不想像这样列出宏。我宁愿有一个表调用宏并调整条件。这可能吗?如何创建一个手动方法较少的方法。所以我可以更新我的条件表而无需更新我的SAS代码。

2 个答案:

答案 0 :(得分:1)

我认为约会可能使事情变得复杂。话虽这么说,你可以在没有引号的情况下传递SAS日期值,你的宏仍然可以工作。如果您有其他区域使用日期,则必须确认它符合您的要求。我通常会使用data _null_步骤,但我将其保存到数据集WANT,这样您就可以看到字符串,如果需要的话。

data want;
set have;

    str = catt('%split_data(', put(month, yymon7.), ",", date1, ",", date2, ",", line, ");");

call execute(str);
run;

答案 1 :(得分:1)

使用您的元数据生成所需的代码。

首先设置一些宏变量(或使用参数创建一个宏)。

%let inds=HAVE;
%let base=WANT ;
%let metadata=METADATA;

然后使用元数据生成单个数据步骤以编写所有输出数据集。

filename code temp;
data _null_;
  set &metadata end=eof;
  file code ;
  if _n_=1 then put 'DATA';
  dsname= catx('_',symget('base'),month,line);
  put @2 dsname ;
  if eof then put ';' / @2 "set &inds;" ;
run;

data _null_;
  set &metadata end=eof;
  file code mod;
  dsname= catx('_',symget('base'),month,line);
  put @2 'IF date > "' date1 date9. '"d and date < "' date2 date9. '"d and line=' line :$quote.
         'then output ' dsname ';'
  ;
  if eof then put 'run;' ;
run;

然后包含生成的代码来运行它。

%inc code / source2 ;

因此,对于您的示例,生成的代码将如下所示:

DATA
 WANT_Jan2010_PL
 WANT_Feb2010_CB
 WANT_Feb2010_HB
 WANT_Mar2010_PL
;
 set HAVE;
 IF date > "01JAN2010"d and date < "31JAN2010"d and line="PL" then output WANT_Jan2010_PL ;
 IF date > "01FEB2010"d and date < "28FEB2010"d and line="CB" then output WANT_Feb2010_CB ;
 IF date > "01FEB2010"d and date < "28FEB2010"d and line="HB" then output WANT_Feb2010_HB ;
 IF date > "01MAR2010"d and date < "31MAR2010"d and line="PL" then output WANT_Mar2010_PL ;
run;