2013-04-04 51 views
1

以下是一些C代码。我如何在sas中做同样的事情?用两个计数器循环

For(i=30, j=1; i<=41, j<=12; i++, j++) 
    (
    closure(i,j) /*calling function with input parameters I and j */ 
    ); 

我基本上要使用循环有两个柜台做以下宏调用I和J

%closure(30,201201); 
%closure(31,201202); 
%closure(32,201203); 
%closure(33,201204); 
%closure(34,201205); 
%closure(35,201206); 
%closure(36,201207); 
%closure(37,201208); 
%closure(38,201209); 
%closure(39,201210); 
%closure(40,201211); 
%closure(41,201212); 

请注意,我不想使用嵌套循环。 小贴士赞赏。

+0

模糊的主题行不太可能对未来的访问者有同样的问题。你甚至没有标记这个问题[sas]! – 2013-04-04 13:30:05

+0

请参阅[在sas中循环](http://blogs.sas.com/content/iml/2011/09/07/loops-in-sas/),然后在DO循环的变体:DO WHILE和DO UNTIL' – 2013-04-04 13:35:40

回答

1

所以,如果你想

  • %关闭(30,201201);
  • %结案(31,201202);
  • %(32,201203);
  • %结案(33,201204);
  • %结案(34,201205);
  • %结案(35,201206);
  • %结案(36,201207);
  • %(37,201208);
  • %结案(38,201209);
  • %结案(39,201210);
  • %结案(40,201211);
  • %结案(41,201212);

那么它会更好,要么你计算J的价值,并把它带到201200左右。 还是应该用201201启动j循环,并最终以201212 干脆提出

对于(I = 30,J = 201201;我< = 41,J < = 201212;我++,J ++)

closure(i,j) 

);

2

在SAS中执行此操作取决于数据的结构。这是可能的:

%do i = 1 to 12; 
    %closure(%eval(29+i),%eval(201200+i)); 
%end; 

这有点奇怪,但它应该工作正常。

你也可以在%闭包宏中做到这一点。通过我,然后确定宏中其他参数的值,如果它们总是有这种关系的话。如果他们总是有一些关系,但2012年和18是可变的,那么你有几种选择:

定义2012年和29宏变量前面这一步的,并且在这样的代码替换它们。

%let year=2012; 
%let startrec=29; 
%do i = 1 to 12; 
    %closure(%eval(&startrec.+&i.),%eval(&year.00+&i.)); 
%end; 

使用日期函数来确定j的值,如果它并不总是01-12。

%closure(30,%sysfunc(intnx(month,'01JUN2011'd,&i.-1))) 

(您可能希望将结果YYYYMM格式格式,也可能只是为富裕使用日期的结果,这取决于%关闭)

定义所有这些术语在数据集,并从数据集中调用宏。

data to_call; 
input i j; 
datalines; 
30 201201 
31 201202 
.... ; 
run; 

proc sql; 
select cats('%closure(',i,',',j,')') into :calllist separated by ' ' from to_call; 
quit; 

&calllist. 

这是一个更加“SAS'sy的方式做事情,做驱动的过程数据。当i和j参数作为数据元素存储在某处(例如在控制表中,或者从其他数据源派生)时,最常用。