如何在SAS中使用宏的循环

时间:2018-06-15 22:50:08

标签: loops macros sas

我有一个关于如何在%宏中使用循环的问题。我写了一个看起来像那样的sas宏:

%macro SortDaysRolling(outdat,var);
proc sort data =  &outdat. (keep=ACM_ACCT_NUM DIM_DATE_ID &var.); by ACM_ACCT_NUM DIM_DATE_ID; run;
%mend SortDaysRolling;

我需要将此函数应用于许多文件,即:

%SortDaysRolling(days_rolling_1_1_1_4,count_times_days_1_4);
%SortDaysRolling(days_rolling_1_1_5_9,count_times_days_5_9);
%SortDaysRolling(days_rolling_1_1_10_14,count_times_days_10_14);
%SortDaysRolling(days_rolling_1_1_15_19,count_times_days_15_19);
%SortDaysRolling(days_rolling_1_1_20_24,count_times_days_20_24);
%SortDaysRolling(days_rolling_1_1_25_29,count_times_days_25_29);
%SortDaysRolling(days_rolling_1_1_30_44,count_times_days_30_44);
%SortDaysRolling(days_rolling_1_1_45_59,count_times_days_45_59);
%SortDaysRolling(days_rolling_1_1_60_89,count_times_days_60_89);
%SortDaysRolling(days_rolling_1_1_90,count_times_days_90);

然后

%SortDaysRolling(days_rolling_1_2_1_4,count_times_days_1_4);
%SortDaysRolling(days_rolling_1_2_5_9,count_times_days_5_9);
%SortDaysRolling(days_rolling_1_2_10_14,count_times_days_10_14);
%SortDaysRolling(days_rolling_1_2_15_19,count_times_days_15_19);
%SortDaysRolling(days_rolling_1_2_20_24,count_times_days_20_24);
%SortDaysRolling(days_rolling_1_2_25_29,count_times_days_25_29);
%SortDaysRolling(days_rolling_1_2_30_44,count_times_days_30_44);
%SortDaysRolling(days_rolling_1_2_45_59,count_times_days_45_59);
%SortDaysRolling(days_rolling_1_2_60_89,count_times_days_60_89);
%SortDaysRolling(days_rolling_1_2_90,count_times_days_90);

所以中间指数发生了变化。由于i = 1,...,35,我不想复制粘贴所有这些行35次。有没有办法做循环?

非常感谢你。

2 个答案:

答案 0 :(得分:2)

您需要确定序列抽象。然后根据它构建排序宏调用。

%macro SortDaysRolling(out, var);
  %put NOTE: &SYSMACRONAME: &=out &=var;
%mend;

%macro sort_loop (I_FROM=1, I_TO=&I_FROM, J_FROM=1, J_TO=&J_FROM);

  %local I J;

  %do I = &I_FROM %to &I_TO;
  %do J = &J_FROM %to &J_TO;

    %SortDaysRolling(days_rolling_&I._&J._1_4,count_times_days_1_4);
    %SortDaysRolling(days_rolling_&I._&J._5_9,count_times_days_5_9);
    %SortDaysRolling(days_rolling_&I._&J._10_14,count_times_days_10_14);
    %SortDaysRolling(days_rolling_&I._&J._15_19,count_times_days_15_19);
    %SortDaysRolling(days_rolling_&I._&J._20_24,count_times_days_20_24);
    %SortDaysRolling(days_rolling_&I._&J._25_29,count_times_days_25_29);
    %SortDaysRolling(days_rolling_&I._&J._30_44,count_times_days_30_44);
    %SortDaysRolling(days_rolling_&I._&J._45_59,count_times_days_45_59);
    %SortDaysRolling(days_rolling_&I._&J._60_89,count_times_days_60_89);
    %SortDaysRolling(days_rolling_&I._&J._90,count_times_days_90);

  %end;
  %end;

%mend;

%sort_loop (J_TO=35);

10个 count_times_days 变量也可以抽象,或者根据生成规则构建。

答案 1 :(得分:0)

生成宏中的数字会缩短代码,同时使其有点神秘。

下面的宏生成表名和varname,并在执行%sortdaysrolling宏块之前检查表是否存在。

%macro SortDaysRolling(outdat,var);
proc sort data =  &outdat. (keep=ACM_ACCT_NUM DIM_DATE_ID &var.); by ACM_ACCT_NUM DIM_DATE_ID; run;
%mend SortDaysRolling;

options mprint mlogic;

%macro sortvarloop;

%do i = 1 %to 2;

    %let j = 1;
    %do %until (&j = 90);

    %if &j = 1 %then %let k = 4;
    %else %let k = %sysevalf(&j + 4)

    %if &j = 90 %then %let tabsuff = %str( );
    %else %let tabsuff = _&k;

        %if %sysfunc(exist(days_rolling_1_&i._&j.&tabsuff.)) %then %do;
        %sortdaysrolling(days_rolling_1_&i._&j.&tabsuff.,count_times_days_&j.&tabsuff.);
        %end;

    %let j = %sysevalf(&j + 5);
    %end;

%end;

%mend sortvarloop; %sortvarloop;

但是如果你真的想要使用一个宏块,你应该先想一想,采用一些命名约定,以便在内存执行上轻松实现。