2013-12-16 39 views
0

我正在参加SAS课程,并有一个项目可以完成。当然,我并不是在寻找确切的答案(尽管那样会很好),但是我们真的很感激正确的方向。使用SAS Macro创建间隔

问题是编写一个宏,该宏创建年龄从一个人年龄的年龄组。给出的代码是:

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

是否需要成为宏?这通常不是实现这一目标的最佳实践。 – Joe

+0

它需要是一个宏。该宏应该能够获取人们年龄的数据集,并根据数据中的年龄范围生成不同范围的if-then/else语句。非常感谢您的快速回复。 – William

+1

我希望这位教授至少在“这是可怕的编程习惯,但是我为了学习的目的而要求你这么做”之前写过? :) – Joe

回答

1

你有一些小问题,但(根据具体要求)通常会有这个问题。

首先,宏需要在数据步骤内执行。然而,你有datalines,这意味着这将无法正常运行 - datalines必须是数据步骤的最后一部分。

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.或任何用于迭代变量的值)。

在现实生活场景中,您可以使用没有宏变量(仅硬编码)的张贴循环,也可以更有效地使用select语句;或者甚至更好地使用格式(proc format)来实现重新编码。格式确实是最好的选择,因为这正是他们所做的,而且他们可以在不需要新的datastep的情况下完成。