0

我已经IF-statement在一个SAS程序中实现了一个基本上检查年份比较有效性的程序。如果IF-statementTRUE一些进一步的变量被初始化和计算,如果IF-statementFALSE什么都没有发生。

但是,我刚刚意识到,无论是IF-statementisTRUE还是FALSE附加变量都将被初始化(尽管MISSING在这种FALSE情况下)并显示在ODS. 这是为什么?有没有直接的方法来解决这个问题?我当然可以使用条件drop-statement,但是总是添加这个似乎很乏味。

data test; 

value = 1;
if value > 2019 then a = 1;

/*
if value < 2019 then 
    do; 
        drop a;
    end;
*/

run;

编辑:我再次意识到,drop-statement无论TRUE/FALSE.

解决方案 ,但不知道为什么有效

data test; 

%let value = 1;
%if &value. > 2019 %then %do; a = 1; %end;

run;

在四处挖掘时,我发现了这个 sas-community post。我的问题似乎基本上源于%IF vs IF. 应用MACRO %IF它的作品。与现在可以MACRO %IFMACRO.

4

2 回答 2

3

这是编译和运行数据步的区别。当数据步被编译时(在它实际运行之前),SAS 会计算出它需要哪些变量。由于该列a位于等式的左侧,因此它被添加到数据集中。请记住,此时,SAS 不知道您将要放入哪些数据;你可能需要那个a专栏,你可能不需要。这就是为什么您不能在运行时有条件地添加/删除列的原因;需要在编译时知道这些列。

在第二种情况下,正如 Tom 指出的那样,宏表达式是在编译数据步之前被评估的。从 SAS 的角度来看,您的代码:

data test; 

%let value = 1;
%if &value. > 2019 %then %do; a = 1; %end;

run;

只是评估这个:

data test; 

run;

另一方面,这段代码:

data test; 

%let value = 2020;
%if &value. > 2019 %then %do; a = 1; %end;

run;

将对此进行评估:

data test; 

a = 1;

run;
于 2019-04-25T17:10:02.683 回答
1

MACRO代码和SAS代码是两个不同的系统。宏处理器首先检查代码并解释任何宏代码(寻找 % 和 & 触发器)。然后生成的文本继续并被评估为 SAS 代码。

因此,在第二种情况下,宏处理器会根据宏变量的值生成不同的 SAS 代码。

另请注意,您的案例正在测试不同的东西。在宏代码中,您正在测试宏变量的值。在数据步骤代码中,您正在测试数据集变量的值(针对特定观察)。

于 2019-04-25T17:04:48.177 回答