当我尝试在SAS中使用宏嵌套循环时出错:
%Let t1=30;
%Let t2=40;
%Let t3=50;
%Let t4=60;
%Let t5=70;
%macro Age(time);
%Do I = 1 %to &time.;
data Milk&I;
set Milk;
/*If Age is less than 30, MilkF and MilkA after 30 should be 0, same for 40-70*/
where (age<&&t&I. and (%Do I = &I. %to 5;
MilkF&&t&I. ne 0 or MilkA&&t&I. ne 0 ;
%end;) ) ;
run;
%end;
%mend Age;
%Age(5)
错误显示在最后一个&#34; ne 0;&#34;语法错误。 问题是什么?谢谢你的帮助!
更新: 我想要的宏的输出是(以t1 = 30为例):
where (age<30 and (
MilkF30 ne 0 or MilkA30 ne 0 or
MilkF40 ne 0 or MilkA40 ne 0 or
MilkF50 ne 0 or MilkA50 ne 0 or
MilkF60 ne 0 or MilkA60 ne 0 or
MilkF70 ne 0 or MilkA70 ne 0
) ) ;
所以我已将代码更改为
where (age<&&t&I. and
(%Do I = &I. %to 5;
MilkFreq&&t&I. ne 0 or MilkAmnt&&t&I. ne 0 or
%end;
) ) ;
错误:
) ) ; run;
-
22
76
&#34;错误:解析WHERE子句时出现语法错误。&#34; 那么现在发生了什么?
答案 0 :(得分:1)
我看到一些不同的错误。考虑:
where (age<&&t&I. and (%Do I = &I. %to 5;
MilkF&&t&I. ne 0 or MilkA&&t&I. ne 0 ;
%end;) ) ;
这会产生:
where (age<30 and (
MilkF30 ne 0 or MilkA30 ne 0 ;
MilkF40 ne 0 or MilkA40 ne 0 ;
MilkF50 ne 0 or MilkA50 ne 0 ;
MilkF60 ne 0 or MilkA60 ne 0 ;
MilkF70 ne 0 or MilkA70 ne 0 ;
) ) ;
如果查看生成的WHERE语句,由于额外的分号,它无效。这会导致错误消息。要解决此问题,请在MilkA&&t&I. ne 0 ;
这些OR条款的逻辑并不像我在评论中描述的那样,所以你可能想要检查。
正如@Reeza指出的那样,你正在使用计数器&amp; i在一个使用计数器&amp; i的循环中。这通常不会导致语法错误,但会导致外部循环过早退出,或者继续无限循环。所以你可以使用&amp; j作为内循环的迭代器。同样最好将&amp; i和&amp; j声明为宏的LOCAL,以避免与外部作用域中任何类似命名的宏变量发生冲突。
更新: 建议你启用OPTIONS MPRINT,然后查看宏生成的代码。通过编辑:
where (age<&&t&I. and
(%do I = &I. %to 5;
MilkFreq&&t&I. ne 0 or MilkAmnt&&t&I. ne 0 or
%end;
) ) ;
你现在有太多的OR,因为它会在最后产生一个额外的OR,即MilkFreq70 ne 0 or MilkAmnt70 ne 0 or ) )
您可以尝试以下方式:
where (age < &&t&i and
(%do j = &i %to 5;
MilkFreq&&t&j ne 0 or MilkAmnt&&t&j ne 0
%if &j ne 5 %then or;
%end;
) ) ;