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

Dear SAS expert

 

I want to use a do-loop to save certain values as macro variables. The purpose is to ease coding. I want to use call symputx to save certain values of a dataset in macro variables. Below is some simplified code to show the issue that I have in the coding. According to the log all macro variables resolve to missing.

 

Can someone pinpoint where my code is incorrect? Thank you 

 

data have;
input id value;
datalines;
1 15
1 22
1 31
1 4
2 10
2 0.5
3 6
3 2
3 7
;
run;

 

 

proc means data=have noprint;
class id;
output out=quartiles(drop=_type_ _freq_)n=n p25=p_25 p50=p_50 p75=p_75;
run;

 

 

%macro extract;


%do jump=1 %to 3;

 

data _null_;
set have;
if id=&jump then call symputx("p_25_&jump.",p_25);
if id=&jump then call symputx("p_50_&jump.",p_50);
if id=&jump then call symputx("p_75_&jump.",p_75);
run;

 

%end;

 

%put &p_25_1;
%put &p_50_1;
%put &p_75_1;
%put &p_25_2;
%put &p_50_2;
%put &p_75_2;
%put &p_25_3;
%put &p_50_3;
%put &p_75_3;

 

%mend;

 

%extract;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26

It always helps to write code that works without macro elements before you create a macro, but very few people follow that advice. If you had followed that advice, you would probably have discovered the problem, which is not a macro problem at all. So I suggest you follow this advice.

 

Here's (a portion of) your code without macros. Can you spot why it doesn't work? If so, fix it and then a similar fix will lead to your macro working.

 

data _null_;
set have;
if id=1 then call symputx("p_25_1",p_25);
if id=1 then call symputx("p_50_1",p_50);
if id=1 then call symputx("p_75_1",p_75);
run;

 

--
Paige Miller

View solution in original post

9 REPLIES 9
PaigeMiller
Diamond | Level 26

It always helps to write code that works without macro elements before you create a macro, but very few people follow that advice. If you had followed that advice, you would probably have discovered the problem, which is not a macro problem at all. So I suggest you follow this advice.

 

Here's (a portion of) your code without macros. Can you spot why it doesn't work? If so, fix it and then a similar fix will lead to your macro working.

 

data _null_;
set have;
if id=1 then call symputx("p_25_1",p_25);
if id=1 then call symputx("p_50_1",p_50);
if id=1 then call symputx("p_75_1",p_75);
run;

 

--
Paige Miller
mgrasmussen
Quartz | Level 8

Dear PaigeMiller

 

Thanks for the reply.

 

I truly cannot spot the issue, but based on your answer, it must be something simple.

mgrasmussen
Quartz | Level 8

Right. The set command. I am referencing the wrong dataset.

Patrick
Opal | Level 21

@mgrasmussen You also don't need all this %do looping.

%macro extract;

  data _null_;
    set quartiles;
    if not missing(id);

    call symputx(cats('p_25_',id),p_25);
    call symputx(cats('p_50_',id),p_50);
    call symputx(cats('p_75_',id),p_75);
  run;

  %put &p_25_1;
  %put &p_50_1;
  %put &p_75_1;
  %put &p_25_2;
  %put &p_50_2;
  %put &p_75_2;
  %put &p_25_3;
  %put &p_50_3;
  %put &p_75_3;
%mend;
PaigeMiller
Diamond | Level 26

@mgrasmussen 

Awesome. Good work.

 

Now here is how to do this without a %DO loop

 

data _null_;
set quartiles(where=(not missing(id)));
call symputx(cats("p_25_",id),p_25);
call symputx(cats("p_50_",id),p_50);
call symputx(cats("p_75_",id),p_75);
run;

%put &p_25_1;
%put &p_50_1;
%put &p_75_1;
%put &p_25_2;
%put &p_50_2;
%put &p_75_2;
%put &p_25_3;
%put &p_50_3;
%put &p_75_3;
--
Paige Miller
mgrasmussen
Quartz | Level 8

Right. Interesting code. Does look more "smooth" than mine with the do loop. Thanks a bunch!

Tom
Super User Tom
Super User

Why are you putting all of the P value into macro variables?

What are you going to do with them?  If you need to use them in further calculations then leave them as actual variables instead and avoid the loss of precision that will occur if you force the values into text strings to be stored into macro variables.

PaigeMiller
Diamond | Level 26

Excellent point by @Tom 

 

Data set QUARTILES could be used in most cases instead of these macro variables, eliminating any potential loss of precision, and in fact eliminating the need to create the macro variables in the first place. So, how will these quartiles be used?

--
Paige Miller
mgrasmussen
Quartz | Level 8

Thanks for the input, Tom and PaigeMiller. I appreciate it.

 

To make a long story short, I calculate quartiles for certain subgroups in a large population, which work as reference quartiles for a subgroup which is nested within the abovementioned population subgroup. Specifically, I calculate the "overall" quartiles and then I use these to categorize a subgroup nested within the overall subgroup. More specifically, I take a general population, compute quartiles within certain age groups, and then categorize a diseased population according to these quartiles within the same age groups for the diseased population. Moreover, I do this for each year (seperate datasets). Therefore, my intuition tells me that the use of macro variables is reasonable, but I would be happy to hear whether or not you agree.

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!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 1587 views
  • 5 likes
  • 4 in conversation