SAS: определение переменных в цикле if
Я новичок в написании макросов SAS, и я изо всех сил пытался написать код для следующего экземпляра.
%let DateOfInterest= "15jul2016"d;
%let yearyyyy=%sysfunc(putn(&DateOfInterest,year4.));
%let yearyyyy2=eval(yearyyyy+1);
data _null_;
if "01JAN2016"d<=&DateOfInterest<="31MAR2016"d then do;
%let reportdate="31MAR2016"d;
%let reportdate2="01APR2016"d;
%let reportdate3="01JAN2016"d;
%let QuarterOfInterest=Q1;
if "31MAR2016"d<&DateOfInterest<="30JUN2016"d then do;
%let reportdate="30JUN2016"d;
%let reportdate2="01JUL2016"d;
%let reportdate3="01APR2016"d;
%let QuarterOfInterest=Q2;
if "30JUN2016"d<&DateOfInterest<="30SEP2016"d then do;
%let reportdate="30SEP2016"d;
%let reportdate2="01OCT2016"d;
%let reportdate3="01JUL2016"d;
%let QuarterOfInterest=Q3;
if "30SEP2016"d<&DateOfInterest<="31DEC2016"d then do;
%let reportdate="31DEC2016"d;
%let reportdate2="01JAN2017"d;
%let reportdate3="01OCT2016"d;
%let QuarterOfInterest=Q4;
end;
end;
end;
end;
run;
Код работает без проблем. Однако независимо от того, какой DateOfInterest я выберу, переменные reportdate оказываются теми, которые указаны в последнем цикле if. Есть ли способ изменить код, чтобы переменная reportdates соответствовала DateOfInterest?
Благодарю.
1 ответ
Вы комбинируете макрос с шагом данных таким образом, что это не работает. Язык макросов и язык шагов данных в основном не связаны: язык макросов может писать код шагов данных, и наоборот, но не может влиять друг на друга в целом.
В частности, макрокод компилируется и выполняется первым, прежде чем открывается какой-либо набор данных или любой код шага данных компилируется или выполняется. В этом-то и дело - это позволяет вам писать прекомпиляцию кода шага данных.
Так
if ... then do;
%let something
end;
Это не работает, потому что сначала выполняется макрос%let, а затем шаг данных.
%if ... %then %do;
%let something
%end;
Это работает, потому что это все на макроязыке. Вообще говоря, если у него нет %
в начале это не оператор / функция макроса, и он не будет работать на языке макроса.
Однако то, что вы делаете, будет иметь некоторые дополнительные сложности. Вы должны быть в макросе, чтобы использовать %if
, но у вас также есть проблемы с областями видимости.
Таким образом, общий небольшой макрос, подобный этому:
%let mval=1;
%macro set_things;
%if &mval=1 %then %do;
%let mval1=1;
%end;
%else %if &mval=2 %then %do;
%let mval2=1;
%end;
%else %do;
%let mval0=1;
%end;
%mend;
%set_things();
%put &=mval &=mval0 &=mval1 &=mval2;
Обратите внимание, что это не работает: потому что это не глобально, поэтому вам нужна еще одна строка внутри макроса:
%global mval0 mval1 mval2;
Это говорит SAS сделать их доступными в глобальном масштабе.