我正在SAS上课并有一个项目要做。我当然不是在寻找确切的答案(尽管那会很好),但是在正确方向上的强力推动将会非常受欢迎。
问题是编写一个宏来创建一个人年龄的年龄组。给出的代码是:
data a ;
infile in1 ;
input name $ age ;
if 30 le age < 33 then agegrp = 30 ;
else if 33 le age < 36 then agegrp = 33 ;
else if 36 le age < 39 then agegrp = 36 ;
else if 39 le age < 42 then agegrp = 39 ;
else if 42 le age < 45 then agegrp = 42 ;
else if 45 le age < 48 then agegrp = 45 ;
else if 48 le age < 51 then agegrp = 48 ;
else if 51 le age < 54 then agegrp = 51 ;
else if 54 le age < 57 then agegrp = 54 ;
else if 57 le age then agegrp = 57 ;
我的工作是编写一个生成if-then / else语句的SAS宏。这是我到目前为止所拥有的。我意识到这不会运行,但我想知道一些东西向你们展示我能在多大程度上完成这项任务。
options ls=78 formdlim=' ' ;
%MACRO CODEIT(start= , stop= , count= , old= , new= );
%let x=&start;
%let y=%eval(&start+&count);
if &start
%do x=&start+&count %to &stop %by &count ;
<= &old < &x then &new=&start ;
%let start=&x ;
else if &start
%end ;
<= &old then &new=&start ;
%MEND
data a ;
input age ;
datalines;
30 31 32 33 34 37
38 39 39 41 42 45
46 46 47 49 50 50
52 53 54 55 56 57
%CODEIT(start=30, stop=57, count=3, old=0, new=0);
我非常感谢你提前得到的所有帮助。
答案 0 :(得分:1)
你有一些小问题,但(鉴于具体要求)通常会有这个问题。
首先,需要在数据步骤内执行宏。但是,你有数据线,这意味着它将无法正常运行 - 数据线必须是数据步骤的最后一部分。
data a;
input age;
<%codeit call>
datalines;
<data>
;;;;
run;
其次,您的%do
控件略有错误。你实际上可以做到这两点;你理论上可以使用%do
,但实际上你应该使用do
。我也会改变开始/结束的工作方式,但这只是个人偏好(我会使start
不是最低值而是最低范围起点;而end
应该是最高范围的结束点,如这对我来说是最合乎逻辑的意义。)
do _iter = &start to &stop by &count;
if _iter. le &old. lt _iter+&count. then &new. = &start.;
end;
if &old. lt &start. then &new.=&start.-&count.;
else if &old. ge &end then &new. = &old.+&count.;
那应该是你的宏。
现在,那说,没有理由为此使用宏;你可以在数据步骤中完成所有这些工作。如果这是一个宏类,那么你可以在%do
中制作大致相同的代码;你仍然希望将整个if
包装在%do
中(你可以使用&_iter.
或你用于迭代变量的任何东西)。
在现实生活中,你可以使用我发布的do循环而不使用宏变量(只是硬编码),或者你可以更有效地使用select
语句;或者,更好的是,使用格式(proc format
)来实现重新编码。格式确实是最好的选择,因为这正是它们的目的,而且无需新的数据操作即可完成。