DATA Step, Macro, Functions and more

macro challenge: groups of 3

Reply
New Contributor
Posts: 3

macro challenge: groups of 3

%macro RunMP;
%do RunMP = 1 %to 5;
%let p1=%eval(&RunMP);
%let p2=%eval(&RunMP+1);
%let p3=%eval(&RunMP+2);
%put &p1 &p2 &p3;
%end;
%mend; %RunMP *;

I've tried everything I can think of... I need distinct sets of three consecutive numbers, so the log output should be
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15

Any thoughts would be appreciated.
Regular Contributor
Posts: 165

Re: macro challenge: groups of 3

Try this (not tested)

%macro RunMP;
%let p1=1;
%do RunMP = 1 %to 5;
%let p2=%eval(&p1+1);
%let p3=%eval(&p2+1);
%put &p1 &p2 &p3;
%let p1=%eval(&p3+1);
%end;
%mend; %RunMP *;
SAS Super FREQ
Posts: 8,862

Re: macro challenge: groups of 3

Hi:
My question is WHERE do you need to have distinct sets of three consecutive numbers??? What good will the numbers in the log do??? Is this part of a bigger program or a different problem???

At any rate, there's nothing wrong with changing the value of &RUNMP inside the %DO loop. So if you changed the ending value to 15
[pre]
%do RunMP = 1 %to 15;
[/pre]

...Since, there's nothing wrong with "resetting" the value of &RUNMP -- and, since the %DO loop will automatically increment by 1...the simplest thing to do after your %PUT is to reset the value of &RUNMP to be equal to the value of &P3:
[pre]
%put &p1 &p2 &p3;
%let RunMP = &p3;
[/pre]

cynthia
Frequent Contributor
Posts: 127

Re: macro challenge: groups of 3

Hello,

You should use the %by option of the %do loop. Your macro becomes:

%macro RunMP;
%do RunMP = 1 %to 5 %by 3;
%let p1=%eval(&RunMP);
%let p2=%eval(&RunMP+1);
%let p3=%eval(&RunMP+2);
%put &p1 &p2 &p3;
%end;
%mend; %RunMP *;


You should also keep in mind that if you have a number of elements to display which is not a multiple of 3, you could see unresolved macro-variables displayed (text '&p1', '&p2' or '&p3' ) in your log... So you should check that each macro-variable you want to display exists prior including its reference in the %put statement.

I hope it helps.

Regards,
Florent
Valued Guide
Posts: 2,177

Re: macro challenge: groups of 3

the %gen() macro and variants has been posted before
Objective is to generate a pattern, subject to cycling numbers, so can simply be 1 2 3 or generate 10 11 12 .

What is confusing me here is the break in groups of 3.
%put NOTE- 1 2 3;
%put note- 4 5 6;
%put note- 7 8 9 ;
demonstrates one way to place text in the log with NOTE coloring, but without the NOTE: prefix.
Was that what "edilts" wanted?

More effective is a data step, like[pre]data _null_ ;
put 'NOTE- 1 2 3';
put 'NOTE- 4 5 6';
put 'NOTE- 7 8 9' ;
run;[/pre]which produces the log[pre]113 data _null_ ;
114 put 'NOTE- 1 2 3';
115 put 'NOTE- 4 5 6';
116 put 'NOTE- 7 8 9' ;
117 run;

1 2 3
4 5 6
7 8 9
NOTE: DATA statement used (Total process time):[/pre]

ymmv
peterC
Respected Advisor
Posts: 3,799

Re: macro challenge: groups of 3

I always like an opportunity to use PROC PLAN. Perhaps a bit of overkill but it may pique your interest in this very useful procedure.

[pre]
%let p=3;
%let r=15;

proc plan ordered;
ods output plan=plan;
factors r=&r p=&p of %sysevalF(&r*&p,I) cyclic(1 to &p)&p;
run;
quit;

data _null_;
set plan;
if _n_ eq 1
then putlog 'NOTE: ' @;
else putlog 'NOTE- ' @;
put (pSmiley Happy (+1 3.);
run;

NOTE: 1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18
19 20 21
22 23 24
25 26 27
28 29 30
31 32 33
34 35 36
37 38 39
40 41 42
43 44 45


[/pre]
New Contributor
Posts: 3

Re: macro challenge: groups of 3

Thank you for the assistance - I used the method described by Florent and it worked perfectly.

My code was just an example; I didn't actually need the numbers in the log, I needed them to plug into another macro loop which was nested inside that one.

Regards,
Erik Message was edited by: edilts
Ask a Question
Discussion stats
  • 6 replies
  • 165 views
  • 0 likes
  • 6 in conversation