简体   繁体   中英

How to use loop with a macro in SAS

I have a question about how to use loop in % macro. I've written a sas macro that looks like that:

%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;

I need to apply this function to a number of files, ie:

%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);

and then

%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);

So the middle index changes. Since i = 1, ..., 35, I don't want to copy-paste all those lines 35 times. Is there any way to do the loop?

Thank you very much.

You need to determine your sequence abstraction. Then construct the sort macro invocations based on that.

%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);

The 10 count_times_days variables could also be abstracted, or constructed from generation rules.

Generating the numbers in-macro would shorten the code whilst making it a bit cryptic.

The below macro generates the table name and varname, and checks if the table exists before executing the %sortdaysrolling macro block.

%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;

But if you really want to use a macro block, you should think a little ahead and adopt some naming convention for easy and less-harsh-on-memory execution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM