Sas 使用宏而不是25个过程sql步骤?

Sas 使用宏而不是25个过程sql步骤?,sas,sas-macro,Sas,Sas Macro,我有一个SAS代码SQL,必须重复25次;关于每个月/年的组合,请参见下面的代码。如何在此代码中使用宏 proc sql; create table hh_oud_AUG_17 as select hh_key ,sum(RG_count) as RG_count_aug_17 ,case when sum(RG_count) >=2 then 1 else 0 end as loyab

我有一个SAS代码SQL,必须重复25次;关于每个月/年的组合,请参见下面的代码。如何在此代码中使用宏

proc sql;
create table hh_oud_AUG_17 as
select   hh_key
        ,sum(RG_count)                                  as RG_count_aug_17
        ,case when sum(RG_count) >=2 then 1 else 0 end  as loyabo_recht_aug_17
from basis_RG_oud
where valid_from_dt <= "01AUG2017"d <= valid_to_dt
group by hh_key
order by hh_key
;
quit;

如果使用数据步骤执行此操作,则可以将所有所需列放在同一输出数据集中,而不是使用宏创建25个单独的数据集:

/*Generate lists of variable names*/
data _null_;
  stem1 = "RG_count_";
  stem2 = "loyabo_recht_";
  month = '01aug2017'd;
  length suffix $4 vlist1 vlist2 $1000;
  do i = 0 to 24;
    suffix = put(intnx('month', month, i, 's'), yymmn4.);
    vlist1 = catx(' ', vlist1, cats(stem1,suffix));
    vlist2 = catx(' ', vlist2, cats(stem2,suffix));
  end;
  call symput("vlist1",vlist1);
  call symput("vlist2",vlist2);
run;

%put vlist1 = &vlist1;
%put vlist2 = &vlist2;

/*Produce output table*/
data want;
  if 0 then set have;
  start_month = '01aug2017'd;
  array rg_count[2, 0:24] &vlist1 &vlist2;
  do _n_ = 1 by 1 until(last.hh_key);
    set basis_RG_oud;
    by hh_key;
    do i = 0 to hbound2(rg_count);
      if valid_from_dt <= intnx('month', start_month, i, 's') <= valid_to_dt 
        then rg_count[1,i] = sum(rg_count[1,i],1);
    end;
  end;
  do _n_ = 1 to _n_;
    set basis_RG_oud;
    do i = 0 to hbound2(rg_count);  
      rg_count[2,i] = rg_count[1,i] >= 2;
    end;    
  end;
run;

创建第二个数据集,该数据集枚举要检查的月份列表。将原始数据交叉连接到第二个数据集。创建一个输出表或视图,其中包含月份作为分类变量,并基于该变量进行聚合。您将能够根据月份变量按分组流程、分类或子集进行分类

data months;
  do month = '01jan2017'd to '31dec2018'd;
    output;
    month = intnx ('month', month, 0, 'E');
  end; 
  format month monyy7.;
run;

proc sql;
  create table want as
  select 
    month, hh_key, 
    sum(RG_count) as RG_count,
    case when sum(RG_count) >=2 then 1 else 0 end  as loyabo_recht
  from 
    basis_RG_oud
  cross join
    months
  where 
    valid_from_dt <= month <= valid_to_dt
  group 
    by month, hh_key
  order 
    by month, hh_key
  ;

…
 /* Some analysis */
    BY MONTH;
…
 /* Some tabulation */
    CLASS MONTH;
    TABLE … MONTH … 
    WHERE year(month) = 2018;         

在SAS中,将数据分割成许多小数据集几乎总是一个坏主意。这会让你以后的生活更加艰难。分组处理或数组处理通常是更好的选择,可以避免编写宏。月份和年份组合的值是多少?@user667489我很高兴你用“几乎总是”来限定它-这在概念上比我的答案中的double-DOW方法要简单一些,但我怀疑由于交叉连接,它将需要更多的运行时间和磁盘空间。
data months;
  do month = '01jan2017'd to '31dec2018'd;
    output;
    month = intnx ('month', month, 0, 'E');
  end; 
  format month monyy7.;
run;

proc sql;
  create table want as
  select 
    month, hh_key, 
    sum(RG_count) as RG_count,
    case when sum(RG_count) >=2 then 1 else 0 end  as loyabo_recht
  from 
    basis_RG_oud
  cross join
    months
  where 
    valid_from_dt <= month <= valid_to_dt
  group 
    by month, hh_key
  order 
    by month, hh_key
  ;

…
 /* Some analysis */
    BY MONTH;
…
 /* Some tabulation */
    CLASS MONTH;
    TABLE … MONTH … 
    WHERE year(month) = 2018;