Sas 直到失踪

Sas 直到失踪,sas,Sas,我的目标是循环遍历一个数组,比如说VAR\uz,这个数组的长度我没有给出。然而,我知道如果VAR\u n缺失,那么VAR\u n+1也会缺失,依此类推。我尝试使用以下类型的%DO%循环: DATA dsn; SET my_dataset; %LET hold = 0; %LET i = 1; %DO %UNTIL (&hold); IF NOT MISSING(VAR_&i) THEN DO; *** Do

我的目标是循环遍历一个数组,比如说
VAR\uz
,这个数组的长度我没有给出。然而,我知道如果
VAR\u n
缺失,那么
VAR\u n+1也会缺失,依此类推。我尝试使用以下类型的
%DO%
循环:

DATA dsn;
    SET my_dataset;
    %LET hold = 0;
    %LET i = 1;

    %DO %UNTIL (&hold);
        IF NOT MISSING(VAR_&i) THEN DO;
            *** Do stuff ;
            CALL SYMPUT('hold', 1);
        END;
        ELSE DO;
            %LET i = %EVAL(&i+1);
        END;
    %END;
RUN;
我曾尝试使用
%LET
而不是
调用SYMPUT
,但似乎执行
%LET
时不考虑条件语句

我尝试过使用
ARRAY MYVAR_u1;
i>DIM(MYVAR)
在我的
%DO%中,直到
,这不起作用。我收到了以下错误: 在表达式(&i>dim(myarr)中找不到所需的运算符 %DO%UNTIL循环中的条件&i>dim(myarr)产生了一个
无效或缺少值

这里的宏代码和数据步骤代码混合在一起,这是您无法做到的。您可能可以这样做:

DATA dsn;
    SET my_dataset;
    array vars var_:;
    do _i = 1 to dim(vars);
       if missing(vars[_i]) then leave; *leaves the loop;
       *_do stuff_;
    end;
RUN;
如果出于某种原因不能,这可能是可能的:

DATA dsn;
    SET my_dataset;
    array vars var_:;
    do _i = 1 to dim(vars);
        if input(scan(vname(vars[_i]),-1,'_'),??best12.) > 0 then do;
          *_do stuff_;
        end;
    end;
RUN;
检查是否有数字后缀;那么它可能在你的变量列表中。这就是它不可能实现的主要原因

如果没有,那么您应该找出数组外部的正确变量端点是什么,然后以这种方式进行编码(例如,获取一个proc内容,找到最高的变量,并将该变量存储在宏变量中,然后
数组变量1-var.&highestnum.
或类似的内容)


你可能还想解释一下你在做什么;这可能不是解决问题的最佳通用方法。

我认为您对SAS宏代码的工作原理存在误解

一般来说,特别是在数据步骤中,宏代码在SAS代码执行之前解析(执行和/或转换为SAS代码)。所以当你说像“%let”这样的东西是在不考虑条件语句的情况下执行的,“实际发生的是在非条件宏之前解析了%let。”

因此,例如,如果您具备以下条件:

if (false) then do;
%let macrovar = 1;
end;
&宏变量。将等于1。如果您想将宏变量置于条件中,您可以改为:

%if 0 %then %do;
%let macrovar = 1;
%end;

它不会执行%let语句。由于宏代码是在执行SAS代码之前解析的,这意味着您不能引用在同一数据步骤中有条件创建的宏变量。要获得更好的、非宏的方式来处理您试图完成的任务,请查看Joe在我打字时所写的内容。

“它不起作用”不是问题陈述。请指定您期望的行为和实际得到的行为。我对SAS不太熟悉,但你似乎过早地结束了你的第一个IF。这非常有效。我确实以一种我无法做到的方式使用了宏和数据步骤代码。谢谢你教我一些东西!