Loops 如何在SAS中使用宏循环

Loops 如何在SAS中使用宏循环,loops,macros,sas,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_roll

我有一个关于如何在%宏中使用循环的问题。我编写了一个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次。有没有办法做这个循环


多谢各位

您需要确定您的序列抽象。然后在此基础上构造排序宏调用

%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变量也可以抽象,或根据生成规则构造。

您需要确定序列抽象。然后在此基础上构造排序宏调用

%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\u days变量也可以被抽象,或者根据生成规则构造。

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

下面的宏生成表名和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;

但是,如果您真的想使用宏块,您应该提前考虑一下,并采用一些命名约定,以便在内存执行时更简单、更不苛刻。

在宏中生成数字会缩短代码,同时使代码有点晦涩

下面的宏生成表名和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;

但是,如果你真的想使用宏块,你应该想得远一点,并采用一些命名约定,以简化和减少对内存执行的苛刻。

你好,Richard。非常感谢你帮我做这个循环。我已经运行过了。这正是我想要的。你好,理查德。我能再问你一个问题吗?如果我需要创建%macro来为文件夹中的每个文件名分配名称,我应该怎么做?例如,文件名inf_1_1'C:\Users\final_complete_1.1.csv';文件名inf_1_2'C:\Users\final_complete_1.2.csv';我怀疑问题在于宏变量解析不会出现在单个引号(
)字符文字中--请尝试使用双引号(
).A
filename
语句定义了一个文件引用--您不太可能需要每个文件都有一个不同的文件引用。在使用引用的文件之前定义一个“通用”文件引用,完成后将其清除。
%do some macro loop;filename FINLDATA“&somepath。\final\u complete\uindex1.\uindex2..csv"; … 用FINLDATA做一些事情…;文件名FINLDATA;%结束/*一些宏循环*/
你好,Richard。非常感谢你帮我做这个循环。我已经运行过了。这正是我想要的。你好,理查德。我能再问你一个问题吗?如果我需要创建%macro来为文件夹中的每个文件名分配名称,我应该怎么做?例如,文件名inf_1_1'C:\Users\final_complete_1.1.csv';文件名inf_1_2'C:\Users\final_complete_1.2.csv';我怀疑问题在于宏变量解析不会出现在单个引号(
)字符文字中--请尝试使用双引号(
).A
filename
语句定义了一个文件引用--您不太可能需要每个文件都有一个不同的文件引用。在使用引用的文件之前定义一个“通用”文件引用,完成后将其清除。
%do some macro loop;filename FINLDATA“&somepath。\final\u complete\uindex1.\uindex2..csv"; … 用FINLDATA做一些事情…;文件名FINLDATA;%结束/*一些宏循环*/
你好,samkart。非常感谢您给我发送此代码。我现在就试试。你好,桑卡特。非常感谢您给我发送此代码。我现在就试试看。