SAS %DO 循环检索多个数据集
SAS %DO Loop to retrieve multiple Datasets
我正在尝试使用 %DO 循环附加多个月度数据文件。这是我目前的代码:
options mprint symbolgen source mlogic merror syntaxcheck ;
%MACRO INT;
%DO i=01 %TO 03 %BY 1;
libname appd "Qual1.Qual2.Qual3.QUAL416&i." disp=shr;
data work&i.;
set appd.file;
run;
data final;
set work;
run;
proc append data=work&i.
base=final;
run;
%MEND;
%INT;
我收到一个错误:
WARNING: The quoted string currently being processed has become more
than 262 characters long. You might have unbalanced quotation
marks.
我以前从未收到过此错误,而且我不完全确定它是什么意思。我正在尝试创建此宏以附加今年的一些文件,但理想情况下它会跨越多年。即改变 mtro16&i。到地铁&我。除非我不想明确地编码 %DO i=1601 %TO 1612 %BY 1
,因为我必须每年更改它,例如如果我从 2010 年开始,我将不得不为 2010 年编写代码,然后为 2011 年编写一个单独的 %DO
语句,等等,一直到 2016 年。这听起来并不多,但十年后 >+ 它可以是。
更新:我更改了我的代码以包含此位:
`%DO i=1005 %TO 1607;
%IF i=1013 %THEN %DO i=1101 %TO 1112;
/*%ELSE %IF i=1113 %THEN %DO i=1201 %TO 1212;*/
/*%ELSE %IF i=1213 %THEN %DO i=1301 %TO 1312;*/
/*%ELSE %IF i=1313 %THEN %DO i=1401 %TO 1412;*/
/*%ELSE %IF i=1413 %THEN %DO i= 1501 %TO 1512;*/
/*%ELSE %IF i=1513 %THEN %DO i=1601 %TO 1607;*/`
这有点笨拙,但我认为只循环到年底然后在 i=1012 to i=1101
之后开始下一次迭代是可行的。然而,这就是我的日志中发生的事情:
MLOGIC(INT): %DO loop index variable I is now 1012; loop will iterate again.
MLOGIC(INT): %IF condition i=1013 is FALSE
MLOGIC(INT): %DO loop index variable I is now 1013; loop will iterate again.
MLOGIC(INT): %IF condition i=1013 is FALSE
SAS 如何处理这种 %IF
情况?它告诉我变量 i = 1013
和 %IF
条件 i=1013
是假的?为什么这不是真的?
这是执行此类循环的一种方法:
%macro month_loop(MTH_FROM, MTH_TO);
%local T_MTH_FROM T_MTH_TO MTH_DIFF CUR_MTH MTH_OFFSET;
%let T_MTH_FROM = %sysfunc(inputn(&MTH_FROM,yymmn.));
%let T_MTH_TO = %sysfunc(inputn(&MTH_TO,yymmn.));
%let MTH_DIFF = %sysfunc(intck(month,&T_MTH_FROM,&T_MTH_TO));
%do MTH_OFFSET = 0 %to &MTH_DIFF;
%let CUR_MTH = %sysfunc(intnx(month,&T_MTH_FROM,&MTH_OFFSET), yymmn4.);
%put CUR_MTH = &CUR_MTH;
%end;
%mend;
%month_loop(1001,1607);
按照你的逻辑有点难,但看起来你只是想做:
data final;
set appd.file work01-work03 ;
run;
我认为在处理日期时,您应该始终实际处理日期值,而不是试图通过使用年或月或其他类似 'shortcuts' 来简化事情。根据我的经验,这些总是会导致代码混乱或错误。
下面是一个宏,它显示了如何传递开始日期和结束日期(甚至不必是一个月的第一天),它将 return 适当的每月名称.然后,您可以根据需要调整它以与您的 proc append
或其他代码一起使用。
它实际上需要2个date值作为参数。然后它使用 %do %while
循环和 intnx()
函数从开始日期循环到结束日期,每次循环 1 个月。我使用 %sysfunc(sum(),yymmn4.)
来计算您每月数据集所需的格式并将其打印到日志中。
代码:
%macro append_monthly(iStart_date=, iEnd_date=);
%local tmp_date id;
%let tmp_date = %sysfunc(intnx(month,&iStart_date,0,beginning)) ;
%do %while (&tmp_date le &iEnd_date);
%let id = %sysfunc(sum(&tmp_date),yymmn4.);
%put &=id;
%let tmp_date = %sysfunc(intnx(month,&tmp_date,1,beginning)) ;
%end;
%mend;
%append_monthly(iStart_date=%sysfunc(mdy(1,1,2010)), iEnd_date=%sysfunc(mdy(1,1,2013)) );
请注意,%sysfunc(sum(&tmp_date),yymmn4.)
是使用宏时格式化数字的一种快捷方式。 %sysfunc()
要求我们提供函数作为第一个参数,您可以选择提供格式作为第二个参数。 sum()
函数很方便,因为它保持数值不变。
输出:
ID=1001
ID=1002
ID=1003
...
ID=1011
ID=1012
ID=1101
ID=1102
ID=1103
...
ID=1110
ID=1111
ID=1112
ID=1201
ID=1202
ID=1203
...
ID=1210
ID=1211
ID=1212
ID=1301
我正在尝试使用 %DO 循环附加多个月度数据文件。这是我目前的代码:
options mprint symbolgen source mlogic merror syntaxcheck ;
%MACRO INT;
%DO i=01 %TO 03 %BY 1;
libname appd "Qual1.Qual2.Qual3.QUAL416&i." disp=shr;
data work&i.;
set appd.file;
run;
data final;
set work;
run;
proc append data=work&i.
base=final;
run;
%MEND;
%INT;
我收到一个错误:
WARNING: The quoted string currently being processed has become more than 262 characters long. You might have unbalanced quotation marks.
我以前从未收到过此错误,而且我不完全确定它是什么意思。我正在尝试创建此宏以附加今年的一些文件,但理想情况下它会跨越多年。即改变 mtro16&i。到地铁&我。除非我不想明确地编码 %DO i=1601 %TO 1612 %BY 1
,因为我必须每年更改它,例如如果我从 2010 年开始,我将不得不为 2010 年编写代码,然后为 2011 年编写一个单独的 %DO
语句,等等,一直到 2016 年。这听起来并不多,但十年后 >+ 它可以是。
更新:我更改了我的代码以包含此位:
`%DO i=1005 %TO 1607;
%IF i=1013 %THEN %DO i=1101 %TO 1112;
/*%ELSE %IF i=1113 %THEN %DO i=1201 %TO 1212;*/
/*%ELSE %IF i=1213 %THEN %DO i=1301 %TO 1312;*/
/*%ELSE %IF i=1313 %THEN %DO i=1401 %TO 1412;*/
/*%ELSE %IF i=1413 %THEN %DO i= 1501 %TO 1512;*/
/*%ELSE %IF i=1513 %THEN %DO i=1601 %TO 1607;*/`
这有点笨拙,但我认为只循环到年底然后在 i=1012 to i=1101
之后开始下一次迭代是可行的。然而,这就是我的日志中发生的事情:
MLOGIC(INT): %DO loop index variable I is now 1012; loop will iterate again.
MLOGIC(INT): %IF condition i=1013 is FALSE
MLOGIC(INT): %DO loop index variable I is now 1013; loop will iterate again.
MLOGIC(INT): %IF condition i=1013 is FALSE
SAS 如何处理这种 %IF
情况?它告诉我变量 i = 1013
和 %IF
条件 i=1013
是假的?为什么这不是真的?
这是执行此类循环的一种方法:
%macro month_loop(MTH_FROM, MTH_TO);
%local T_MTH_FROM T_MTH_TO MTH_DIFF CUR_MTH MTH_OFFSET;
%let T_MTH_FROM = %sysfunc(inputn(&MTH_FROM,yymmn.));
%let T_MTH_TO = %sysfunc(inputn(&MTH_TO,yymmn.));
%let MTH_DIFF = %sysfunc(intck(month,&T_MTH_FROM,&T_MTH_TO));
%do MTH_OFFSET = 0 %to &MTH_DIFF;
%let CUR_MTH = %sysfunc(intnx(month,&T_MTH_FROM,&MTH_OFFSET), yymmn4.);
%put CUR_MTH = &CUR_MTH;
%end;
%mend;
%month_loop(1001,1607);
按照你的逻辑有点难,但看起来你只是想做:
data final;
set appd.file work01-work03 ;
run;
我认为在处理日期时,您应该始终实际处理日期值,而不是试图通过使用年或月或其他类似 'shortcuts' 来简化事情。根据我的经验,这些总是会导致代码混乱或错误。
下面是一个宏,它显示了如何传递开始日期和结束日期(甚至不必是一个月的第一天),它将 return 适当的每月名称.然后,您可以根据需要调整它以与您的 proc append
或其他代码一起使用。
它实际上需要2个date值作为参数。然后它使用 %do %while
循环和 intnx()
函数从开始日期循环到结束日期,每次循环 1 个月。我使用 %sysfunc(sum(),yymmn4.)
来计算您每月数据集所需的格式并将其打印到日志中。
代码:
%macro append_monthly(iStart_date=, iEnd_date=);
%local tmp_date id;
%let tmp_date = %sysfunc(intnx(month,&iStart_date,0,beginning)) ;
%do %while (&tmp_date le &iEnd_date);
%let id = %sysfunc(sum(&tmp_date),yymmn4.);
%put &=id;
%let tmp_date = %sysfunc(intnx(month,&tmp_date,1,beginning)) ;
%end;
%mend;
%append_monthly(iStart_date=%sysfunc(mdy(1,1,2010)), iEnd_date=%sysfunc(mdy(1,1,2013)) );
请注意,%sysfunc(sum(&tmp_date),yymmn4.)
是使用宏时格式化数字的一种快捷方式。 %sysfunc()
要求我们提供函数作为第一个参数,您可以选择提供格式作为第二个参数。 sum()
函数很方便,因为它保持数值不变。
输出:
ID=1001
ID=1002
ID=1003
...
ID=1011
ID=1012
ID=1101
ID=1102
ID=1103
...
ID=1110
ID=1111
ID=1112
ID=1201
ID=1202
ID=1203
...
ID=1210
ID=1211
ID=1212
ID=1301