2017-05-03 5 views
0

SAS 매크로 작성에 익숙하지 않아 다음 인스턴스에 대한 코드 작성에 어려움을 겪고 있습니다.SAS : if 루프의 변수 정의

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

, 나중에 데이터 단계가 발생합니다.

%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가 글로벌 영역에서 사용할 수 있도록합니다.

+0

안녕하세요. 당신의 반응에 대해 많은 감사드립니다. 나는 % global 공식을 정확하게 이해하지 못했습니다. 그러나 위에 제공된 샘플을 사용하더라도 마지막 루프 (% put & reportdate = & reportdate2 = & reportdate3 =; "31DEC2016"d = "01JAN2017"d = "01OCT2016"d =)에 정의 된 값을 reportdates가 사용합니다. 나는 reportdates가 올바른 루프를 따르지 않고 마지막 가능한 값을 취하는 이유를 이해하지 못합니다. 이걸 좀 도와 주시겠습니까? – FioravanteL