简体   繁体   English

SAS%DO循环以检索多个数据集

[英]SAS %DO Loop to retrieve multiple Datasets

I'm trying to use a %DO loop to append multiple monthly data files. 我正在尝试使用%DO循环来附加多个每月数据文件。 Here's the code I have so far: 这是我到目前为止的代码:

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;

I'm getting an error : 我遇到一个错误:

WARNING: The quoted string currently being processed has become more than 262 characters long. 警告:当前正在处理的带引号的字符串的长度超过262个字符。 You might have unbalanced quotation marks. 您可能有不平衡的引号。

I've never received this error before, and I'm not entirely sure what it means. 我以前从未收到过此错误,我也不完全知道这意味着什么。 I'm trying to create this macro to append a few files from this year, but ideally it would span across multiple years. 我正在尝试创建此宏来添加今年的一些文件,但理想情况下,它会跨越多年。 ie changing mtro16&i. 即更改mtro16&i。 to mtro&i. 去地铁&i。 EXCEPT I don't want to have to code %DO i=1601 %TO 1612 %BY 1 explicitly, because I will have to change it for every year, eg if I begin in 2010, i'll have to code 2010, then a separate %DO statement for 2011, etc. all the way until 2016. This doesn't sound like much, but across a decade >+ it can be. 除非我不想显式地编码%DO i=1601 %TO 1612 %BY 1 ,因为我每年都必须对其进行更改,例如,如果我从2010年开始,则必须编码2010,然后直到2011年为止,都是针对2011年的单独%DO语句,直到2016年。这听起来并不多,但是十多年以来就可以了。

UPDATE: I changed my code to include this bit: 更新:我更改了代码以包括以下内容:

`%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;*/`

It's kind of janky, but I thought it would work to only loop to the end of the year and then begin the next iteration after i=1012 to i=1101 . 有点过时,但我认为只循环到年末然后在i=1012 to i=1101之后开始下一次迭代是可行的。 However, this is what is happening in my log: 但是,这就是我的日志中发生的事情:

 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

How is SAS treating this %IF condition? SAS如何治疗这种%IF疾病? It tells me that variable i = 1013 and that %IF condition i=1013 is FALSE? 它告诉我变量i = 1013%IF条件i=1013为FALSE? Why is this not TRUE? 为什么这不是TRUE?

Here's one way of doing such a loop: 这是进行这种循环的一种方法:

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

I think when working with dates, you should always actually work with date values rather than trying to shortcut things by using years or months or other such 'shortcuts'. 我认为在处理日期时,应始终实际使用日期值,而不要尝试通过使用年或月或其他类似的“快捷方式”来缩短日期。 In my experience, these always lead to confusing and or buggy code. 以我的经验,这些总是会导致代码混乱或错误。

Below is a macro that shows how you can pass in a start date and an end date (that don't even have to be the 1st of the month) and it will return the appropriate monthly names. 下面的宏显示了如何传递开始日期和结束日期(甚至不必是每月的1号),它将返回适当的每月名称。 You can then adapt this to work with your proc append or other code as desired. 然后,您可以根据需要proc append进行修改以使其与proc append或其他代码一起使用。

It actually takes 2 date values as parameters. 实际上,它需要2个日期值作为参数。 It then uses a %do %while loop and the intnx() function to loop from the start date to the end date 1 month at a time. 然后,它使用%do %while循环和intnx()函数一次从开始日期到结束日期循环1个月。 I use %sysfunc(sum(),yymmn4.) to calculate the desired format for your monthly datasets and print it to the log. 我使用%sysfunc(sum(),yymmn4.)为您的每月数据集计算所需的格式,并将其打印到日志中。

Code: 码:

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

Note that the %sysfunc(sum(&tmp_date),yymmn4.) is kind of a shortcut for formatting a number when using macros. 请注意, %sysfunc(sum(&tmp_date),yymmn4.)是使用宏格式化数字时的一种快捷方式。 %sysfunc() requires us to provide a function as the first parameter, and you can optionally provide a format as the second parameter. %sysfunc()要求我们提供一个函数作为第一个参数,您可以选择提供格式作为第二个参数。 The sum() function is convenient because it leaves the numeric value unchanged. sum()函数很方便,因为它使数值保持不变。

Output: 输出:

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

It is a little hard to follow your logic, but it looks like you just want to do: 遵循您的逻辑有些困难,但是看起来您只想这样做:

data final;
  set appd.file work01-work03 ;
run;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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