如何在 1 个脚本中使用 SAS - PROC SQL、IF THEN 语句和 Do 循环?

How to use SAS - PROC SQL, IF THEN statement and a Do loop in 1 script?

希望有人能帮我解决我的问题。

对于我工作的公司,我需要检查每月发送给我的数据集中是否有可用数据。如果没有可用数据,则 SAS 必须停止脚本并给出错误(这不是问题,问题出在该部分之前)。问题如下: 我们使用非常大的数据集。将新数据与旧数据进行比较,以便检查新数据和之前 11 个月的数据。我和我的流行病学家同事们写下了我们想要检查的月份,并将其写入一个名为 'deliveryfile' 的预先设计的宏变量中。这无法更改,因此需要将此宏变量包含在脚本中。我想做一个循环来检查数据集中是否存在一个月(或几个月)。如果它存在,则什么也不会发生。如果不存在,则将月份添加到预先存在的数据集中。

示例数据集和宏变量:

DATA existingdataset;
INPUT yearmonth total;
DATALINES;
202108 400
202109 0
202110 450
;
RUN;

%LET deliveryfile = 202110, 202111;

使用上面的代码,我需要编写一个脚本来检查现有数据集中是否已经存在月份 202110 和 202111。 202110 存在,所以什么也不会发生。 202111 不存在,因此需要将其添加到 'existingdataset'。只需要添加月份,变量 'total' 将是 empty/NULL.

这是我想出来的,但我遇到了几个错误,大部分与我使用 PROC SQL 的方式有关。 第 1 位:

PROC SQL NOPRINT;
    SELECT DISTINCT yearmonth INTO :yearmonth SEPARATED BY ', ' FROM existingdataset;
QUIT;
%PUT NOTE: yearmonth : &yearmonth; /*For verification */

%MACRO ADDING;
DATA existingdataset;
    SET existingdataset;
    IF 
        %DO i=1 %TO %SYSFUNC(COUNTW("&deliveryfile "));
            %LET ymcontrol=%SCAN(%QUOTE(&deliveryfile ),&i,%STR( ));
            &ymcontrol NOT IN (&yearmonth)
        %END
            THEN; 
        PROC SQL;
            INSERT INTO existingdataset
            SET yearmonth= &ymcontrol;
        QUIT;
    END;
RUN;
%MEND ADDING;
%ADDING;

然后我想,也许我可以同时使用 PROC SQL、IF THEN 和 DO 循环,但这也不起作用。

PROC SQL NOPRINT;
    SELECT DISTINCT yearmonth INTO :yearmonth SEPARATED BY ', ' FROM existingdataset;
QUIT;
%PUT NOTE: yearmonth : &yearmonth; /*For verification */

%MACRO ADDING;
PROC SQL;
    IF 
        %DO i=1 %TO %SYSFUNC(COUNTW("&deliveryfile "));
            %LET ymcontrol=%SCAN(%QUOTE(&deliveryfile ),&i,%STR( ));
            &ymcontrol NOT IN (&yearmonth)
        %END
            THEN; 
                INSERT INTO existingdataset
                SET yearmonth= &ymcontrol;
    END;
QUIT;
%MEND ADDING;
%ADDING;

我希望有人能回答我的问题。

如果有人有更好的想法一次性完成所有事情(检查月份,制作一个 table 可视化哪个月份或哪个月份不正确,然后停止脚本)我愿意接受也。我现在将完全解释脚本需要做什么。 最终,脚本需要做的是检查 (1) 数据集 (existingdataset) 中是否存在月份 (deliveryfile) 以及 (2) 数据集中是否存在月份总数为 0 或无.如果有一个月份的总数为 0 或什么都没有,那么脚本需要 (1) 制作一个 table 只包含一个或多个月份,总数为 0 且没有任何内容进入日志,(2)在 de log 中添加一条注释,指出“注意:语法已停止”,并且 (3) 退出脚本的其余部分,但不会完全中止 SAS。如果一切顺利,脚本将继续执行其余部分。 我已经尝试写下一些东西,但还没有完成。

DATA _NULL_;
    %IF total = 0 %THEN %DO;
            PROC SQL;
                CREATE TABLE nototal_details AS
                    SELECT DISTINCT yearmonth, total
                    FROM existingdataset
                    WHERE total= 0
                    ORDER BY yearmonth DESCENDING;
            QUIT;
         /* Still need to write a part that puts that table into the LOG*/
        %PUT NOTE: Syntax has stopped.;
        %ABORT CANCEL;
    %END;
RUN;

因此,在我上面给出的示例中,最终脚本需要在 SAS 停止之前在日志中提供此 table: |没有信息的月份|总计| |:------------------------|----:| |202109 | 0 | |202111 |空|

听起来您只需要创建一个数据集,其中包含您想要强制存在的值列表,并将其与您的实际数据合并。

data required;
  do yearmonth = 202110, 202111 ;
     output;
  end;
run;
data want;
  merge existingdataset required;
  by yearmonth;
run;

所以如果你有这个宏变量:

%LET deliveryfile = 202110, 202111;

这非常适合用于生成所需的 DO 语句。

data required;
  do yearmonth = &deliveryfile ;
     output;
  end;
run;

因此不需要宏代码(宏变量引用除外)或 SQL。