DATA Step, Macro, Functions and more

Dynamic Do Loop

Reply
Occasional Contributor
Posts: 6

Dynamic Do Loop

Team,

 

I have the following code:

 

%let char_var_cnt=12;
%let sixpack=6;
%let quotient=%eval(&char_var_cnt./&sixpack.);
%let remainder=%sysfunc(mod(&char_var_cnt.,&sixpack.));
%put quotient=&quotient.;
%put remainder=&remainder.;

%macro looping;
	%do i=1 %to &sixpack.;
		%do k=1 %to &char_var_cnt.;
			%let k&i._&k.=var&k.;
			%put list is k&i._&k.;
		%end;
	%end;
%mend;

%looping;

 The above code creates macro variable

 

list is k1_1
list is k1_2
list is k1_3
list is k1_4
list is k1_5
list is k1_6
list is k1_7
list is k1_8
list is k1_9
list is k1_10
list is k1_11
list is k1_12
list is k2_1
list is k2_2
list is k2_3

list is k2_4
list is k2_5
list is k2_6
list is k2_7

 

What I actually want is:

It creates the following macro variable

k1_1 K1_2

k2_3 K2_4

k3_1 K3_6

k4_1 K4_8

k5_9 K5_10

k6_11 K6_12

 

Each of these K1_1, k1_2, k2_3 etc macro variables need to take value from another macro var&i.

 

The char_var_cnt macro variable is dynamic.

 

The sixpack  macro variable is static.

 

To summarize:

If char_var_cnt is equal to 12 then i want the following macro parameters:

k1_1 K1_2

k2_3 K2_4

k3_1 K3_6

k4_1 K4_8

k5_9 K5_10

k6_11 K6_12

 

If char_var_cnt is equal to 24 then i want the following macro parameters:

k1_1   K1_2   k1_3   K1_4
k2_5   K2_6   k2_7   K2_8
k3_9   K3_10 k3_11 K3_12
k4_13 K4_14 k4_15 K4_16
k5_17 K5_18 k5_19 K5_20
k6_21 K6_22 k6_23 K6_24

 

 

Can you please help me with it?

Super User
Posts: 13,347

Re: Dynamic Do Loop

Posted in reply to arpitsharma27

You have created the macro variables, at least temporarily, but you didn't examine the values properly. Please see:

 

%macro looping;
	%do i=1 %to &sixpack.;
		%do k=1 %to &char_var_cnt.;
			%let k&i._&k.=var&k.;
			%put list k&i._&k. is &&k&i._&k.;
		%end;
	%end;
%mend;

I do not have any of your var&k variables to examine but to get the value of them you could use

 

%macro looping;
	%do i=1 %to &sixpack.;
		%do k=1 %to &char_var_cnt.;
			%let k&i._&k.= &&var&k.;
			%put list k&i._&k. is &&k&i._&k.;
		%end;
	%end;
%mend;

If you want the variables to exist outside of your macro looping you will have do something something additional such as add a %global statement as each is created. Otherwise the only exist inside your loop macro.

 

You can use %put with key words to generate lists of macro variables and their values without having to %put each one.

See:

%macro looping;
	%do i=1 %to &sixpack.;
		%do k=1 %to &char_var_cnt.;
			%let k&i._&k.= var&k.;
			
		%end;
	%end;
   %put _local_;
%mend;
Occasional Contributor
Posts: 6

Re: Dynamic Do Loop

Here is the revised code:

I have provided a snippet of log.

The ones that i DONT want are highlighted RED.

The ones that I WANT are highlighted GREEN.

 

%macro alpha(start=,stop=);

	%do z=&start. %to &stop.;
	%global var&z.;
		%let var&z.=alpha&z.;
	%end;
%mend;
%alpha(start=1,stop=12);

%let char_var_cnt=12;
%let sixpack=6;
%let quotient=%eval(&char_var_cnt./&sixpack.);
%let remainder=%sysfunc(mod(&char_var_cnt.,&sixpack.));
%put quotient=&quotient.;
%put remainder=&remainder.;

%macro looping;
	%do i=1 %to &sixpack.;
		%do k=1 %to &char_var_cnt.;
			%let k&i._&k.=&&var&k.;
			%put list is k&i._&k. &&k&i._&k.;
		%end;
	%end;
%mend;

%looping;

I get this in log:

list is k1_1 alpha1
list is k1_2 alpha2
list is k1_3 alpha3
list is k1_4 alpha4
list is k1_5 alpha5

list is k1_6 alpha6
list is k1_7 alpha7
list is k1_8 alpha8
list is k1_9 alpha9
list is k1_10 alpha10
list is k1_11 alpha11
list is k1_12 alpha12
list is k2_1 alpha1
list is k2_2 alpha2
list is k2_3 alpha3
list is k2_4 alpha4
list is k2_5 alpha5

list is k2_6 alpha6
list is k2_7 alpha7
list is k2_8 alpha8
list is k2_9 alpha9

......

Super User
Super User
Posts: 7,938

Re: Dynamic Do Loop

Posted in reply to arpitsharma27

@arpitsharma27 wrote:

Here is the revised code:

I have provided a snippet of log.

The ones that i DONT want are highlighted RED.

The ones that I WANT are highlighted GREEN.

 

 

......


What is the LOGIC for deciding which once to create? Can you describe it in words?

I don't see the pattern in this list.

list is k1_1 alpha1
list is k1_2 alpha2
list is k2_3 alpha3
list is k2_4 alpha4

Are you just setting K equal to CEIL(ALPHA/2)?

Try getting the looping logic right in a data step where it is easier to debug and then translating to macro logic.  or just use CALL SYMPUTX() to generate the macro variables in the data step.

 

 

Super User
Super User
Posts: 7,938

Re: Dynamic Do Loop

Posted in reply to arpitsharma27

Coding is much easier in data steps.  Plus the DO loop is much more powerful than the %DO loop.

Not sure what you want to do but I can generate your pattern of K and ALPHA values using data steps like this.  

I added extra DO loops so you can play with settings of two input numbers and see how it works.

data _null_;
  do sixpack=6;
    do char_var_cnt=12,24,17 ;
      put / sixpack= char_var_cnt= / 12*'-' ;
      alpha=1 ;
      do k=1 by 1 while (alpha <= char_var_cnt) ;
        put k= @;
        do i=1 to ceil(char_var_cnt/sixpack) while (alpha <= char_var_cnt);
         put alpha= @;
         alpha+1;
        end;
        put;
      end;
    end;
  end;
run;
sixpack=6 char_var_cnt=12
------------
k=1 alpha=1 alpha=2
k=2 alpha=3 alpha=4
k=3 alpha=5 alpha=6
k=4 alpha=7 alpha=8
k=5 alpha=9 alpha=10
k=6 alpha=11 alpha=12

sixpack=6 char_var_cnt=24
------------
k=1 alpha=1 alpha=2 alpha=3 alpha=4
k=2 alpha=5 alpha=6 alpha=7 alpha=8
k=3 alpha=9 alpha=10 alpha=11 alpha=12
k=4 alpha=13 alpha=14 alpha=15 alpha=16
k=5 alpha=17 alpha=18 alpha=19 alpha=20
k=6 alpha=21 alpha=22 alpha=23 alpha=24

sixpack=6 char_var_cnt=17
------------
k=1 alpha=1 alpha=2 alpha=3
k=2 alpha=4 alpha=5 alpha=6
k=3 alpha=7 alpha=8 alpha=9
k=4 alpha=10 alpha=11 alpha=12
k=5 alpha=13 alpha=14 alpha=15
k=6 alpha=16 alpha=17
Ask a Question
Discussion stats
  • 4 replies
  • 95 views
  • 0 likes
  • 3 in conversation