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

I am trying to learn the SAS %MACRO procedure but something is not working correctly. I am using the SasHelp.PriceData data set and am trying to write some simply code to calculate the median and coefficient of variation for each price feature (preice1-price17). I am running the below code. When I invoke my %DO_Median macro I expect there to be 17 Median_&I table, however the macro does not seem to be generating any output as currently written. What am i missing or not understanding about the %MACRO syntax?

 

%MACRO DO_MEDIAN;
%DO I=1 %TO I=17;

	PROC MEANS DATA=SasHelp.PriceData NOPRINT;
		VAR price&I;
		OUTPUT OUT=work.Medians_&I  Median=Med_&I CV=CV_&I;
	RUN;

%END;
%MEND DO_MEDIAN;

%DO_MEDIAN;
1 ACCEPTED SOLUTION

Accepted Solutions
andreas_lds
Jade | Level 19

The first thing you have to understand is, that the macro language is nothing more, but a code-generator or text-replacing-system. You start writing macros, when you have code that you want/have to execute multiple times.

 

And please don't not write all code in upcase, it makes reading unnecessary difficult.

 

Replace the line

%DO I=1 %TO I=17

 with

%DO I=1 %TO 17;

View solution in original post

8 REPLIES 8
andreas_lds
Jade | Level 19

The first thing you have to understand is, that the macro language is nothing more, but a code-generator or text-replacing-system. You start writing macros, when you have code that you want/have to execute multiple times.

 

And please don't not write all code in upcase, it makes reading unnecessary difficult.

 

Replace the line

%DO I=1 %TO I=17

 with

%DO I=1 %TO 17;
Reeza
Super User

Remember to check your log. 

 

You can add the following code to your macros to help with debugging:

options mprint symbolgen;
options mlogic;

I find the MLOGIC can add to much so I don't always use that, but you should be aware it exists when working with macros. 

 


@tgrandchamp wrote:

I am trying to learn the SAS %MACRO procedure but something is not working correctly. I am using the SasHelp.PriceData data set and am trying to write some simply code to calculate the median and coefficient of variation for each price feature (preice1-price17). I am running the below code. When I invoke my %DO_Median macro I expect there to be 17 Median_&I table, however the macro does not seem to be generating any output as currently written. What am i missing or not understanding about the %MACRO syntax?

 

%MACRO DO_MEDIAN;
%DO I=1 %TO I=17;

	PROC MEANS DATA=SasHelp.PriceData NOPRINT;
		VAR price&I;
		OUTPUT OUT=work.Medians_&I  Median=Med_&I CV=CV_&I;
	RUN;

%END;
%MEND DO_MEDIAN;

%DO_MEDIAN;

 

PaigeMiller
Diamond | Level 26

I understand this is a learning exercise, but I hope you also realize that there's no need for macros in this situation.

 

PROC MEANS DATA=SasHelp.PriceData NOPRINT;
    VAR price1-price17;
    OUTPUT OUT=work.medians median=med_1-med_17 cv=cv_1-cv_17;
RUN;
--
Paige Miller
ballardw
Super User

@tgrandchamp wrote:

I am trying to learn the SAS %MACRO procedure but something is not working correctly. I am using the SasHelp.PriceData data set and am trying to write some simply code to calculate the median and coefficient of variation for each price feature (preice1-price17). I am running the below code. When I invoke my %DO_Median macro I expect there to be 17 Median_&I table, however the macro does not seem to be generating any output as currently written. What am i missing or not understanding about the %MACRO syntax?

 

%MACRO DO_MEDIAN;
%DO I=1 %TO I=17;

	PROC MEANS DATA=SasHelp.PriceData NOPRINT;
		VAR price&I;
		OUTPUT OUT=work.Medians_&I  Median=Med_&I CV=CV_&I;
	RUN;

%END;
%MEND DO_MEDIAN;

%DO_MEDIAN;

An aside on the way you are creating your output variable names. Prefixing related values with the statistic may depending on how you use  the resulting data make it harder to reference values. If you want to select all of the similar price1 variables it may be more cumbersome. MAY.

SAS does provide a way to append the statistic as suffix to the variable name. Coupled with that plus the variable list you perhaps could do something like:

 

Proc means data=sashelp.pricedata noprint;
   var price: ;
   output out=work.medians median= cv= /autoname;
run;

Calculating all of the values in one pass.

 

Then if you only want to use the values for Price8 later select using Keep= Price8_: ;

The : attached to part of variable name selects all variables that start with that text. So the VAR statement in proc means above is asking to summarize all variables whose names start with PRICE.

If I thought I really needed the variables to start with the statistic , then I might do something like:

%MACRO DO_MEDIAN;


	PROC MEANS DATA=SasHelp.PriceData NOPRINT;
		VAR 
      %DO I=1 %TO 17;
      price&I.
      %end;
      ; /* this semicolon ends the VAR statement*/
		OUTPUT OUT=work.Medians  
      Median=  %DO I=1 %TO 17; Med_&I. %end; 
      CV= %DO I=1 %TO 17; CV_&I. %end;
      ;
	RUN;


%MEND DO_MEDIAN;

%do_median;

to select the variables and specifically name them but in one pass instead of creating 17 different data sets.

Kurt_Bremser
Super User

Most likely (I'm on my tablet, so can't test it at the moment) this happens:

I=17

is a boolean condition that evaluates to false (which is a numeric zero in SAS, as in most programming environments). The text "I" can never be equal to the text "17".

So your macro do statement evaluates to

%do i = 1 %to 0;

and the loop never executes.

 

SAS iterative do statements differ from the "for" in C, where you would write

for (i=1;i<=17;i++) {

putting the continuation condition in as the second element, not a target value.

Kurt_Bremser
Super User

And to clear up a misconception:

%macro is not a procedure, it is a macro statement that invokes the SAS macro preprocessor, so you are switching to a different syntactic environment that is similar in many aspects to Base SAS, but also vastly different in many others.

Tom
Super User Tom
Super User

What do you think is the upper value for I for this %do loop?

%DO I=1 %TO I=17;

What value do you get in the log if you run this statement?

%put I=17;

 

cnm8191
Fluorite | Level 6

I am a little late responding, but I found the following article on %MACRO while studying. I hope this helps!

 

https://support.sas.com/resources/papers/proceedings/proceedings/sugi24/Handson/p149-24.pdf

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 6405 views
  • 1 like
  • 8 in conversation