BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
meighanj
Obsidian | Level 7

 

I have this SAS code to iterate a macro variable in a DATA statement. I want to recreate this idea except inside a macro, however, I am sturgglying with this. 

 

data A;
	%let y=1;
	do i = 1 to 5;
   		y = &y + i;
   		output;
	end;
run;

%macro test();
	%let y=1;
	%do j=1 %to 5;
		y = &y + &j;
	%end;
%mend test;

 

1 ACCEPTED SOLUTION

Accepted Solutions
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Its a common misunderstanding.  There are two parts to the SAS system:

Base SAS - this is the programming language, has all the data types, functions etc.  It should be used 99% of the time.

Macro - this is a text find/replace system, which happens before the compilation phase.  It is only there to generate text (which may be code).  

The two systems are distinct and do not overlap.  So when looking at macro code, you just need to see what text it generates:

1)

%let y=1;             /* Note its good practice to put let statements outside base code */
data A; do i = 1 to 5; y = &y. + i; /* Note its good practice to put a . after all macro variables */ output; end; run;

Resolves after the pre-processor to:

 

data A;
  do i = 1 to 5;
    y = 1 + i;
    output;
  end;
run;

 Which is valid Base code and will output the rows given in the do loop to a dataset.

2) 

%macro test();
  %let y=1;
  %do j=1 %to 5;
    y = &y. + &j.;
  %end;
%mend test;
%test;

Resolves after the pre-processor to:

y = 1 + 1;
y = 1 + 2;
y = 1 + 3;
y = 1 + 4;
y = 1 + 5;

 Which as you can see, on its own is not valid Base SAS code.

 

In this example it is clear that using the data step is the way forward, there is nothing to be gained by creating macro code, and you will just end up with a messier less perfomant version.  Macro does have a use, but replacing Base SAS is not it.  Now to correct your second code:

%macro test();
  %let y=1;
  %do j=1 %to 5;
    y = &y. + &j.;
    output;
  %end;
%mend test;

data want;
  %test;
run;

View solution in original post

3 REPLIES 3
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Its a common misunderstanding.  There are two parts to the SAS system:

Base SAS - this is the programming language, has all the data types, functions etc.  It should be used 99% of the time.

Macro - this is a text find/replace system, which happens before the compilation phase.  It is only there to generate text (which may be code).  

The two systems are distinct and do not overlap.  So when looking at macro code, you just need to see what text it generates:

1)

%let y=1;             /* Note its good practice to put let statements outside base code */
data A; do i = 1 to 5; y = &y. + i; /* Note its good practice to put a . after all macro variables */ output; end; run;

Resolves after the pre-processor to:

 

data A;
  do i = 1 to 5;
    y = 1 + i;
    output;
  end;
run;

 Which is valid Base code and will output the rows given in the do loop to a dataset.

2) 

%macro test();
  %let y=1;
  %do j=1 %to 5;
    y = &y. + &j.;
  %end;
%mend test;
%test;

Resolves after the pre-processor to:

y = 1 + 1;
y = 1 + 2;
y = 1 + 3;
y = 1 + 4;
y = 1 + 5;

 Which as you can see, on its own is not valid Base SAS code.

 

In this example it is clear that using the data step is the way forward, there is nothing to be gained by creating macro code, and you will just end up with a messier less perfomant version.  Macro does have a use, but replacing Base SAS is not it.  Now to correct your second code:

%macro test();
  %let y=1;
  %do j=1 %to 5;
    y = &y. + &j.;
    output;
  %end;
%mend test;

data want;
  %test;
run;
meighanj
Obsidian | Level 7

Ok, very interesting thank you. I am working on a macro from an existing code so it's hard to alter it too much. What do you think of this work around found following your advice?

 

 

%macro test();
	%let y=1;
	data A; 
		do i = 1 to 5;
			y = &y. + i;
    		output;
 		end;
	run;
%mend test;

%test;

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

The question is more general than that.  The question is: Does wrapping some plain simple Base SAS code in macro add any value to the process.  The answer from what I can see, and in almost all macro code I have seen over the years, is no it doesn't add anything.  All it does is make the code messy, longer, and harder to maintain.  

Look at it this way, from what you post, just counting the characters you have to type, the code with macro is longer.  Now it is also harder to read as you have to see where it gets resolved, this on the other hand:

data A;
  do i = 1 to 5;
    y = 1 + i;
    output;
  end;
run;

Very easy to read, no need to work out resolutions.

Possibly your example is a simplified version, can't really say without seeing it. 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 2024 views
  • 4 likes
  • 2 in conversation