我的代码是:
libname " Cp/mydata"
options ;
%let yyyymmdd=20050210;
%let offset=0;
%let startrange=0;
%let endrange=0;
/* MACRO FOR INCREMENTING THE DATE */
%macro base(yyyymmdd=, offset=);
%local date x ds; /* declare macro variables with local scope */
%let date=%sysfunc(mdy(%substr(&yyyymmdd,5,2)
,%substr(&yyyymmdd,7,2)
,%substr(&yyyymmdd,1,4))); /* convert yyyymmdd to SAS date */
%let loopout=100;/* hardcoded - number of times to check whether ds exists */
%do x=&offset %to &loopout; /* begin loop */
/* convert &date to yyyymmdd format */
%let ds=AQ.CO_%sysfunc(intnx(day,&date,&offset),yymmddn8.);
%if %sysfunc(exist( &ds )) %then %do;
%put &ds exists!;
&ds /* write out the dataset, if it exists */
%let x=&loopout; /* exit loop */
%end;
%else %do;
%put &ds does not exist - checking subsequent day;
%let date=&date+1;
%end;
%end;
%mend;
%macro loop(yyyymmdd=, startrange=, endrange=);
%local date x ds;
%let date=%sysfunc(mdy(%substr(&yyyymmdd,5,2)
,%substr(&yyyymmdd,7,2)
,%substr(&yyyymmdd,1,4)));
data x;
set set %base(yyyymmdd=&yyyymmdd, offset=0)
/* loop through each specific dataset, checking first whether it exists.. */
%do x=&startrange %to &endrange;
%let ds=AQ.CO_%sysfunc(intnx(day,&date,&x),yymmddn8.);
%if %sysfunc(exist( &ds )) %then %do;
&ds
%end;
%end;
;
run;
%mend;
这是我尝试运行此宏时生成的错误。
数据临时;
58 set%loop(yyyymmdd =& yyyymmdd,startrange =& startrange, 58! endrange =安培; endrange);
错误:文件WORK.DATA.DATA不存在。
错误:文件WORK.X.DATA不存在。
AQ.CO_20050210不存在 - 检查后续日
AQ.CO_20050211不存在 - 检查后续日
AQ.CO_20050212存在!
注意:由于错误,系统停止处理此步骤。
我想要两方面的帮助:
1)在这里,如果我的原始数据集中没有该日期,我正试图将日期增加1或2左右。请帮助使这个宏工作正常。
2)我想在我的数据中有另一列,即work.date,它将具有0或1(如果指定日期yyyymmdd存在于我们的原始数据中,则为1,如果我正在递增,则为0)。请在我的宏中进行指定的更改。 在此先感谢!!
答案 0 :(得分:1)
我不太确定你的%base()
宏正在尝试实现什么,但我注意到了一些事情。
首先尝试打开option mprint;
以帮助调试。如果您仍需要更多调试信息,您也可以尝试打开以下选项(我建议您一次1个,直到您知道需要哪些选项):
option symbolgen macrogen mlogic;
其次,您的示例代码中只有set set
而不是set
。我不认为这有助于任何=)。
当我在我的机器上快速尝试代码时,我注意到当我调用%base()
宏时,我遇到了一个奇怪的错误(与你的不同)。这似乎是一个不应该发生的错误所以我将调用包裹在%unquote()
函数中以确保并且我开始收到您的帖子提到的错误。您可能也想尝试这个:
set %unquote(%base(yyyymmdd=&yyyymmdd, offset=0))
通常不需要%unquote()
函数,除非您明确使用宏引用函数并获得奇怪的错误,但SAS宏有时似乎有自己的想法。当我知道这是必要的时候,我只会添加它。
此外,您的libname调用在行尾没有分号。
最后,关于使用SAS宏语言中的日期的一些建议。不要在日期值和格式化值之间进行转换。它会使您的代码更大,更容易出错并且更难以阅读。我知道,因为我过去常常这样做。请尝试始终使用包含实际日期值的变量(通过使用%sysfunc(mdy())
的结果),然后如果需要格式化值,则创建一个新变量(例如%let yyyymmdd = %sysfunc(putn(&mydate),yymmddn8.);
。当您通过时从一个宏到另一个宏的值,即使看起来更容易也不会传递格式化值,传递实际值。
进行上述更改会删除计算机上的所有错误。最终代码:
libname " Cp/mydata";
%let yyyymmdd=20050210;
%let offset=0;
%let startrange=0;
%let endrange=0;
/* MACRO FOR INCREMENTING THE DATE */
%macro base(yyyymmdd=, offset=);
%local date x ds; /* declare macro variables with local scope */
%let date=%sysfunc(mdy(%substr(&yyyymmdd,5,2)
,%substr(&yyyymmdd,7,2)
,%substr(&yyyymmdd,1,4))); /* convert yyyymmdd to SAS date */
%let loopout=100;/* hardcoded - number of times to check whether ds exists */
%do x=&offset %to &loopout; /* begin loop */
/* convert &date to yyyymmdd format */
%let ds=AQ.CO_%sysfunc(intnx(day,&date,&offset),yymmddn8.);
%if %sysfunc(exist( &ds )) %then %do;
%put &ds exists!;
&ds /* write out the dataset, if it exists */
%let x=&loopout; /* exit loop */
%end;
%else %do;
%put &ds does not exist - checking subsequent day;
%let date=&date+1;
%end;
%end;
%mend;
%macro loop(yyyymmdd=, startrange=, endrange=);
%local date x ds;
%let date=%sysfunc(mdy(%substr(&yyyymmdd,5,2)
,%substr(&yyyymmdd,7,2)
,%substr(&yyyymmdd,1,4)));
data x;
set %unquote( %base(yyyymmdd=&yyyymmdd, offset=0))
/* loop through each specific dataset, checking first whether it exists.. */
%do x=&startrange %to &endrange;
%let ds=AQ.CO_%sysfunc(intnx(day,&date,&x),yymmddn8.);
%if %sysfunc(exist( &ds )) %then %do;
&ds
%end;
%end;
;
run;
%mend;
%loop(yyyymmdd=&yyyymmdd, startrange=&startrange, endrange=&endrange);
答案 1 :(得分:0)
在我看来,您的解决方案非常复杂。 但我相信至少有一个问题是我们的第二个宏(%循环)中的变量x:我看不到你在哪里定义它。
如果您不需要限制循环,您可以更轻松地完成所有这些操作。如果您只想要偏移量以外的所有数据集,可以通过使用SASHELP库来查找所需的数据集来简化所有这些操作。然后只是循环结果。
弃用回复,误读了需要 你正在重新发明轮子,深入研究intnx和intck函数。 http://support.sas.com/documentation/cdl/en/etsug/60372/HTML/default/viewer.htm#etsug_tsdata_sect038.htm https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000212700.htm