我有一个关于如何在%宏中使用循环的问题。我写了一个看起来像那样的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次。有没有办法做循环?
非常感谢你。
答案 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;
但是如果你真的想要使用一个宏块,你应该先想一想,采用一些命名约定,以便在内存执行上轻松实现。