【问题标题】:%if %then %do condition not resolved%if %then %do 条件未解决
【发布时间】:2019-09-17 11:38:23
【问题描述】:

我继承了下面的块似乎没有解决的宏。宏应该根据日期值有条件地选择逻辑操作。如果满足 %if 条件,它们应该打印 %put 语句中提到的宏变量,这些变量又成为 if 条件的一部分。如果满足条件 %if %length(&datein.)=10 OR %length(ST_&date.)=10,它将打印第一个 %put 语句,否则将打印第二个 %put 语句。同样的逻辑适用于第二个 %if 语句。

宏应该在数据步骤中运行。逻辑运算符 AND 被视为变量,我收到一条注释注意:变量 AND 未初始化。

我试图通过添加下面代码中提到的左括号和右括号来平衡 if 条件。试图改变 if 条件的结构以分隔第一个和第二个条件,但似乎不起作用。我假设逻辑运算符 AND 不能像在 %if %then %else 语句中那样使用。

%macro test_date(date=, comp1=, comp2=, label=);
            if &datein. ne "" and ST_&date. ne "" then do;
                if (%if %length(&datein.)=10 OR %length(ST_&date.)=10 %then %put ST_&date._10 &comp1. datein_10; %else %put ST_&date._19 &comp1. datein_19;
                AND %if %length(&datein.)=10 OR %length(ED_&date.)=10 %then %put datein_10 &comp2. ED_&date._10; %else %put datein_19 &comp2. ED_&date._19;)
                then EPOCH=&label.;
            end;
%mend test_date;

%test_date(date=SCREEN, comp1= le, comp2= le, label='SCREEN');

【问题讨论】:

  • 这对我来说没有多大意义。它是ifthenelseepoch(而不是%if%then%else%let epoch),所以我认为它应该在数据步骤中运行?内部 if 中的内容写入日志,并且在数据步骤运行时不会解析为 true 或 false。 And 不能在语句中排在第一位。 ST_&date 似乎是外部 if 中的数据步骤变量和内部 if 中的字符串。这应该怎么做?
  • 抱歉没有说清楚。我已经更新了我的问题。
  • 你希望宏做什么?您希望宏生成什么 SAS 代码?
  • 显示您尝试使用此宏生成的数据步骤的其余部分。
  • 如果满足 %if 条件,他们应该打印 %put 语句中提到的宏变量,这些变量又成为 if 条件的一部分。这段代码 sn-p 是庞大代码的一部分,会很乏味。

标签: if-statement sas sas-macro


【解决方案1】:

您可能需要稍微调整一下,但这应该有助于理清它的逻辑。下面的代码检查宏变量的长度,并根据这个长度插入数据步骤代码。它还会将一些值打印到日志中,但这不会影响结果。我已经包含了一些简单的数据步骤示例来说明它是如何工作的。

%macro test_date(date=, comp1=, comp2=, label=);
    %if &datein. ne  and &&ST_&date. ne  %then %do;

        %if %length(&datein.)=10 OR %length(&&ST_&date.)=10 %then %do;
            /*  Insert data step code */
            if variable1=1 then epoch="First condition";
            else epoch="firstelse";
            /*  Print to log*/
            %put &&ST_&date. &comp1. &datein.; 
        %end;
        %else %if %length(&datein.)=10 OR %length(&&ED_&date.)=10 %then %do;
            if variable1=0 then epoch="Second condition";
            else epoch="secondelse";
        %end;

    %end;
%mend test_date;

/*  Macro variables given values of length 10. Outer if and first condition in do block holds.*/
%let datein=0123456789;
%let st_screen=0123456789;
%let ed_screen=0123456789;

data test1;
    variable1=1;
    %test_date(date=SCREEN, comp1= le, comp2= le, label='SCREEN');
run;


data test2;
    variable1=0;
    %test_date(date=SCREEN, comp1= le, comp2= le, label='SCREEN');
run;

/*  Macro variables given values of length 9 and 10. Outer if and else condition in do block holds.*/
%let datein=012345678;
%let st_screen=012345678;
%let ed_screen=0123456789;


data test3;
    variable1=1;
    %test_date(date=SCREEN, comp1= le, comp2= le, label='SCREEN');
run;

data test4;
    variable1=0;
    %test_date(date=SCREEN, comp1= le, comp2= le, label='SCREEN');
run;

/*  Macro variables are empty. Outer if is false. The macro does nothing.  */
%let datein=;
%let st_screen=;
%let ed_screen=;


data test5;
    variable1=1;
    %test_date(date=SCREEN, comp1= le, comp2= le, label='SCREEN');
run;

data test6;
    variable1=0;
    %test_date(date=SCREEN, comp1= le, comp2= le, label='SCREEN');
run;

【讨论】:

    【解决方案2】:

    您的程序没有任何意义。如果我们忽略可能会向 LOG 生成消息的 %IF 语句,则您的宏正在生成此 SAS 代码:

    if &datein. ne "" and ST_&date. ne "" then do;
      if ( AND  ) then EPOCH=&label.;
    end;
    

    由于您使用变量AND 作为 IF 语句的条件,SAS 将假定它是一个数字变量并测试其值是否非零且非缺失。如果没有名为AND 的变量,那么它的值将丢失,因此EPOCH 的值将永远不会改变。

    如果您希望宏对宏可变长度进行这些测试,则将该宏逻辑从您尝试生成的 SAS 代码的中间拉出。

    让我们看看第一个 %IF/%THEN 语句。

    %if %length(&datein.)=10 OR %length(ST_&date.)=10 
      %then %put ST_&date._10 &comp1. datein_10; 
    %else %put ST_&date._19 &comp1. datein_19;
    

    所以你正在测试宏变量DATEIN的长度是10字节还是宏变量DATE的长度是7字节(常量文本ST_总是3字节长)。

    【讨论】:

    • 抱歉不清楚。我更新了我的问题,让您更清楚。
    猜你喜欢
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多