我有2个SAS宏循环-1个用于创建时间序列数据集,另一个用于将数据集附加到主数据集。 宏Date_loop1创建时间序列数据集。在此示例中,我将创建虚拟数据集。实际上,实际数据集的大小为几MB。因此,在Date_loop1中使用proc追加到主数据集会导致进度缓慢。因此,我创建了第二个宏Date_loop2,以将以上所有数据集堆叠在SET语句中。问题是第二个循环未按预期工作。你能帮忙吗?
注意:如果运行Date_loop1,则可以看到如何创建数据集。 Date_loop2也应该以类似的方式工作。
%MACRO LOOP1;
DATA ROLLRATE_&ST_YYYYMM._&ED_YYYYMM.;
ST_YYYYMM = &ST_YYYYMM;
ED_YYYYMM = &ED_YYYYMM;
RUN;
%MEND;
%MACRO DATE_LOOP1(START,END);
%LET START_YEAR = %SYSFUNC(FLOOR(&START/100));
%LET START_MONTH = %SYSFUNC(MOD(&START,100));
%LET END_YEAR = %SYSFUNC(FLOOR(&END/100));
%LET END_MONTH = %SYSFUNC(MOD(&END,100));
%LET START_DATE = %SYSFUNC(MDY(&START_MONTH,01,&START_YEAR));
%LET END_DATE = %SYSFUNC(MDY(&END_MONTH,01,&END_YEAR));
%LET DIF=%EVAL(%SYSFUNC(INTCK(MONTH,&START_DATE,&END_DATE)));
/*DATA MASTER_ROLLRATE;RUN;DATA ROLLRATE;RUN;*/
%DO I=0 %TO &DIF;
%DO J=&I %TO &DIF;
%LET ST_DT = %SYSFUNC(INTNX(MONTH,&START_DATE,&I,B)); /*B - DATE AT THE BEGINNING OF THE WEEK/MONTH/YEAR */
%LET ST_YEAR = %SYSFUNC(YEAR(&ST_DT));
%LET ST_MONTH = %SYSFUNC(MONTH(&ST_DT));
%LET ST_YYYYMM = %EVAL(&ST_YEAR*100+&ST_MONTH);
%LET ED_DT = %SYSFUNC(INTNX(MONTH,&START_DATE,&J,B));
%LET ED_YEAR = %SYSFUNC(YEAR(&ED_DT));
%LET ED_MONTH = %SYSFUNC(MONTH(&ED_DT));
%LET ED_YYYYMM = %EVAL(&ED_YEAR*100+&ED_MONTH);
%PUT &ST_YYYYMM &ED_YYYYMM;
%LET START_YYYYMM = &ST_YYYYMM;%LET END_YYYYMM = &ED_YYYYMM;%LOOP1;RUN;
%END;
%END;
%MEND DATE_LOOP1;
%DATE_LOOP1(201901,201902);
%MACRO DATE_LOOP2(START,END);
%LET START_YEAR = %SYSFUNC(FLOOR(&START/100));
%LET START_MONTH = %SYSFUNC(MOD(&START,100));
%LET END_YEAR = %SYSFUNC(FLOOR(&END/100));
%LET END_MONTH = %SYSFUNC(MOD(&END,100));
%LET START_DATE = %SYSFUNC(MDY(&START_MONTH,01,&START_YEAR));
%LET END_DATE = %SYSFUNC(MDY(&END_MONTH,01,&END_YEAR));
%LET DIF=%EVAL(%SYSFUNC(INTCK(MONTH,&START_DATE,&END_DATE)));
DATA MASTER_ROLLRATE;
SET
%DO I=0 %TO &DIF;
%DO J=&I %TO &DIF;
%LET ST_DT = %SYSFUNC(INTNX(MONTH,&START_DATE,&I,B)); /*B - DATE AT THE BEGINNING OF THE WEEK/MONTH/YEAR */
%LET ST_YEAR = %SYSFUNC(YEAR(&ST_DT));
%LET ST_MONTH = %SYSFUNC(MONTH(&ST_DT));
%LET ST_YYYYMM = %EVAL(&ST_YEAR*100+&ST_MONTH);
%LET ED_DT = %SYSFUNC(INTNX(MONTH,&START_DATE,&J,B));
%LET ED_YEAR = %SYSFUNC(YEAR(&ED_DT));
%LET ED_MONTH = %SYSFUNC(MONTH(&ED_DT));
%LET ED_YYYYMM = %EVAL(&ED_YEAR*100+&ED_MONTH);
%LET START_YYYYMM = &ST_YYYYMM;%LET END_YYYYMM = &ED_YYYYMM;
ROLLRATE_&START_YYYYMM._&END_YYYYMM;
%END;
%END;
;
RUN;
%MEND DATE_LOOP1;
%DATE_LOOP2(201901,201902);
答案 0 :(得分:2)
您可以在SET
语句中使用名称列表,并完全避免使用宏。
每个名称以rollrate
开头的数据集都会被堆叠:
data want;
set work. rollrate:;
run;
答案 1 :(得分:1)
打开MPRINT选项以查看宏正在生成什么代码。第二个是生成类似以下的代码:
MPRINT(DATE_LOOP2): data master_rollrate;
MPRINT(DATE_LOOP2): set rollrate_201901_201901;
NOTE: Line generated by the macro variable "ED_YYYYMM".
1 rollrate_201901_201902
----------------------
180
MPRINT(DATE_LOOP2): rollrate_201901_201902;
NOTE: Line generated by the macro variable "ED_YYYYMM".
1 rollrate_201902_201902
----------------------
180
MPRINT(DATE_LOOP2): rollrate_201902_201902;
MPRINT(DATE_LOOP2): ;
MPRINT(DATE_LOOP2): run;
在嵌套%do
循环的中间删除多余的分号,因为您仅在这些循环中生成语句的PART。
通过使用格式和格式将YYYYMM数字字符串与实际日期值相互转换,可以大大简化宏代码。
%macro date_loop2(start,end);
%local start_date end_date dif i j st_yyyymm ed_yyyymm;
%let start_date = %sysfunc(inputn(&start.01,yymmdd8));
%let end_date = %sysfunc(inputn(&end.01,yymmdd8));
%let dif=%sysfunc(intck(month,&start_date,&end_date));
data master_rollrate;
set
%do i=0 %to &dif;
%do j=&i %to &dif;
%let st_yyyymm = %sysfunc(intnx(month,&start_date,&i,b),yymmn6);
%let ed_yyyymm = %sysfunc(intnx(month,&start_date,&j,b),yymmn6);
rollrate_&st_yyyymm._&ed_yyyymm
%end;
%end;
;
run;
%mend date_loop2;