S T
S T

Reputation: 13

Loop with two counters

Following is some C code. How do I do the same in sas?

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

I basically want to do the following macro calls using a loop with two counters I and 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);

Please note that I do not want to use a nested loop. Tips are appreciated.

Upvotes: 1

Views: 687

Answers (2)

Joe
Joe

Reputation: 63424

Doing this in SAS depends on how your data is structured. It's possible to do this:

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

That's a bit odd, but it should work fine.

You could also do it in the %closure macro. Pass i and then determine the value of the other parameters inside the macro, if they always have this relationship. If they always have some relationship, but the 2012 and 18 parts are variable, then you have several options:

Define 2012 and 29 as macro variables ahead of this step, and replace them in the code with such.

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

Use date functions to determine the value of j, if it is not always 01-12.

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

(you may want to format the result in YYYYMM format, or you may be just as well off using the date result, depending on %closure)

Define all of these terms in a dataset, and call the macro from the dataset.

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.

That's a more 'SAS'sy way to do things, making the process data driven. Most commonly used when the i and j parameters are stored as data element somewhere (in a control table, for example, or derived from some other data source).

Upvotes: 2

Nitesh Sethia
Nitesh Sethia

Reputation: 113

So If you want

  • %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);

then it would be better either you calculate the value of J and bring it to 201200 aur something near about. Or you should start the j loop with 201201 and end it to 201212 simply go for

For(i=30, j=201201; i<=41, j<=201212; i++, j++)

(

  closure(i,j) 

);

Upvotes: 1

Related Questions