我的目标是遍历一个数组,比如说VAR_
一些我没有给出的长度。但是,我知道如果缺少VAR_n
,那么VAR_n+1
也是如此,依此类推。我的尝试是使用以下变种的%DO %UNTIL
循环:
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
代替CALL SYMPUT
,但似乎执行%LET
而不考虑条件语句。
我已尝试在ARRAY MYVAR VAR_:;
中使用i > DIM(MYVAR)
和%DO %UNTIL
,但这不起作用。我收到以下错误:
在表达式中找不到所需的运算符:& i>暗淡(myArr,该)
%DO%UNTIL循环中的条件,& i>昏暗的(myarr),产生了一个
无效或缺失值。
答案 0 :(得分:1)
您正在以一种您不能的方式混合宏和数据步骤代码。你可能会这样做:
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内容,找到最高的var _ ####,和将####存储在宏变量中,然后array vars var_1-var_&highestnum.;
或类似的东西。)
你也可能想解释一下你还在做什么;这可能不是解决问题的最佳方法。
答案 1 :(得分:0)
我认为您对SAS宏代码的工作方式存在误解。
一般而言,特别是在数据步骤中,在SAS代码执行之前,宏代码被解析(执行和/或转换为SAS代码)。所以当你说"%let执行时,不考虑条件语句,"实际发生的是%let在非宏条件之前得到解决。
因此,例如,如果您有以下内容:
if (false) then do;
%let macrovar = 1;
end;
&安培; macrovar。将等于1.如果你想将macrovar放在条件中,你可以改为:
%if 0 %then %do;
%let macrovar = 1;
%end;
哪个不会执行%let语句。因为在执行SAS代码之前解析宏代码,这意味着您无法引用在相同数据步骤中有条件地创建的宏变量。为了更好,非宏观的方式来处理你想要完成的事情,看看乔在我输入时写的是什么。