【问题标题】:SAS : definition of variables in if loopSAS:if循环中的变量定义
【发布时间】:2017-05-03 14:40:39
【问题描述】:

我是 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?

谢谢。

【问题讨论】:

    标签: sas sas-macro


    【解决方案1】:

    您正在以一种行不通的方式将宏与数据步骤结合起来。宏语言和数据步语言基本没有关系:宏语言可以写数据步代码,反之亦然,但一般互不影响。

    特别是,宏代码首先编译和执行,然后再打开任何数据集或编译或执行任何数据步骤代码。这才是真正的重点——它可以让你编写 datastep 代码预编译。

    所以

    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 让它们在全球范围内可用。

    【讨论】:

    • 嗨。非常感谢您的回复。我不确定是否正确理解了 %global 公式。但是,即使我使用您在上面提供的示例,reportdates 也会采用上一个循环中定义的值 (%put &reportdate= &reportdate2= &reportdate3=; "31DEC2016"d= "01JAN2017"d= "01OCT2016"d=)。我不明白为什么reportdates 不遵循正确的循环并且只取最后一个可能的值。你能帮我解决这个问题吗?
    猜你喜欢
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 2011-12-05
    • 2015-12-20
    相关资源
    最近更新 更多