使用SAS宏创建间隔

时间:2013-12-16 16:27:05

标签: macros sas intervals

我正在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);

我非常感谢你提前得到的所有帮助。

1 个答案:

答案 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)来实现重新编码。格式确实是最好的选择,因为这正是它们的目的,而且无需新的数据操作即可完成。