SAS中的宏循环 - 将值传递给条件

时间:2018-01-13 13:51:22

标签: database loops if-statement macros sas

我是SAS的初学者,我在SAS中的宏循环中苦苦挣扎。下面的代码说明了这个问题。这里的任务是创建单独的子集并将它们保存为库以供以后的后处理。另外,我添加了可视化图表。我在一个庞大的数据库上运行,但是为了这篇文章,我在代码的开头创建了一个示例,以简化。

但是,似乎内部条件(IF ID = i)不会过滤掉数据。相反,内部循环创建空表(但具有正确的名称:" SUB1"," SUB2"," SUB3"),其中一列(变量)称为&#34 ; I"

DATA EXAMPLE;

INPUT ID DATE DDMMYY8. VALUE;
FORMAT DATE DDMMYY8.;
DATALINES;
1 01012011 100
1 01022011 400
1 01032011 678
2 01012011 678
2 01022011 333
2 01032011 333
3 01012011 733
3 01022011 899
3 01032011 999
;
%MACRO filter(number);
    %DO i=1 %TO &number;
        DATA SUB&i;
        SET WORK.EXAMPLE;
        IF ID = i;
        PROC SGPLOT DATA=SUB&i;
        reg x=DATE y=VALUE;
        RUN;
    %END;
%mend filter;

%filter(3);

如果我手动将部件复制并粘贴到宏内并手动将i更改为数字1到3,则会创建正确的图形。这段代码有什么问题?如何从代码中的DO语句传递值?

我正在使用SAS Studio。

3 个答案:

答案 0 :(得分:2)

宏正在创建空数据集,因为宏最终写入的代码包含子集if语句

if ID = i;

由于数据集不包含变量i,因此将名为i的新变量添加到PDV和输出数据集SUB1SUB2,{{ 1}}。缺少SUB3的默认值,并且缺少ID值,因此没有行通过测试,您将获得空数据集。日志还将提供有关情况的线索:

i

在为“宏观化”抽象代码段时,请确保在宏变量前面使用NOTE: Variable i is uninitialized. 。因此,当宏包含

&

宏系统编写的最终代码将使用宏变量的不同值进行3次类似的代码操作。

if ID = &i;

答案 1 :(得分:0)

现在您生成相同的图形三次,因为数据集SUB1,SUB2,SUB3都使用相同的数据集。这是因为数据步骤中唯一依赖于宏变量I的值的是名称。

您当前正在选择变量ID与变量I匹配的观察值。也许您打算选择变量ID%DO循环中使用的宏变量匹配的观察值?

IF ID = &i;

答案 2 :(得分:0)

调试宏代码的一个技巧是添加语句

options mprint;

这将显示SAS实际使用的代码。

例如在日志中:

70   options mprint;
71   %MACRO filter(number);
72       %DO i=1 %TO &number;
73           DATA SUB&i;
74           SET WORK.EXAMPLE;
75           IF ID = &i;
76           PROC SGPLOT DATA=SUB&i;
77           reg x=DATE y=VALUE;
78           RUN;
79       %END;
80   %mend filter;
81
82   %filter(2);
MPRINT(FILTER):   DATA SUB1;
MPRINT(FILTER):   SET WORK.EXAMPLE;
MPRINT(FILTER):   IF ID = 1;

NOTE: There were 9 observations read from the data set WORK.EXAMPLE.
NOTE: The data set WORK.SUB1 has 3 observations and 3 variables.
NOTE: DATA statement used (Total process time):
      real time           0.03 seconds
      cpu time            0.01 seconds


MPRINT(FILTER):   PROC SGPLOT DATA=SUB1;
MPRINT(FILTER):   reg x=DATE y=VALUE;
MPRINT(FILTER):   RUN;