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

Hi,

 

I am running the following macro

 

%macro geomeans (data=, outcome=);

	%let total_vars = %sysfunc (countw (&outcome) );
	%do i = 1 %to &total_vars;
		%let selected_var=%scan (&outcome, &i);

               ods output estimates=geomeans&i; 
			proc genmod data=&data;
				class brinda15 / param = glm;
     			model &outcome = brinda15 / type3 dist=normal ;
						estimate "Overall estimate &outcome brinda15 =0" intercept 1 brinda15 1 0  /exp; 
						estimate "Overall estimate &outcome brinda15 =1 " intercept 1 brinda15 0 1  /exp; 
			run;
		ods output close;
I call the macro with the following code:
%geomeans (data=db, outcome=var1 var2 var3)
It works only for the first variable (it doesn't matter which one it is), but for the other variables I the error message below 
Screenshot 2024-05-24 at 6.32.33 PM.png
In case it matters, my outcomes are continuous and ln transformed.
Any tips of how to fix this are welcome! 
 
Thank you
 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

Based on extensive macro language experience, but zero genmod experience:

 

It is unusual to create the macro variable &SELECTED_VAR but then never use it.  Is it possible that your MODEL statement is supposed to refer to &SELECTED_VAR, not &OUTCOME?

 

The same could easily apply to the ESTIMATE statements as well (although that appears to be a label and wouldn't cause an error, just a labeling issue).,

View solution in original post

8 REPLIES 8
Astounding
PROC Star

Based on extensive macro language experience, but zero genmod experience:

 

It is unusual to create the macro variable &SELECTED_VAR but then never use it.  Is it possible that your MODEL statement is supposed to refer to &SELECTED_VAR, not &OUTCOME?

 

The same could easily apply to the ESTIMATE statements as well (although that appears to be a label and wouldn't cause an error, just a labeling issue).,

Stanley3
Obsidian | Level 7

thank you! that solved it. Now it's doing the cycle for all. my outcome variables. However, it is not working for a piece of my code below (which I omitted in the original question for simplicity). Using the mprint option, I can see that the macro-generated code does not seem to recognize &selected_var. I wonder if you know what could be wrong. 

 
%macro geomeans (data=, outcome=);

%let total_vars = %sysfunc (countw (&outcome) );
%do i = 1 %to &total_vars;
%let selected_var=%scan (&outcome, &i);

        ods output estimates=geomeans&i; 
proc genmod data=&data;
class brinda15 / param = glm;
      model &selected_var = brinda15 / type3 dist=normal ;
estimate "Overall estimate &selected_var brinda15 =0" intercept 1 brinda15 1 0  /exp; 
estimate "Overall estimate &selected_var brinda15 =1" intercept 1 brinda15 0 1  /exp; 
by rural;
run;
ods output close;

data geomeans&i; set geomeans&i; 
variable='&selected_var'; 
lower=LBetaEstimate - stderr;                                                                                                                 
upper=LBetaEstimate + stderr;
if rural=0 then setting='urban'; else if rural=1 then setting='rural';
if (label='Exp(Overall estimate &selected_var brinda15 =0)') then iron_def=0; 
else if (label='Exp(Overall estimate &selected_var brinda15 =1)') then iron_def=1;
if iron_def=. then delete;
if iron_def=0 then iron_status='serum ferritin  ≥15 µg'; 
else if iron_def=1 then iron_status='serum ferritin <15 µg';
keep label iron_def variable LBetaEstimate StdErr lower upper rural iron_status setting;
run;

quit;
    %end;

%mend;
Log 
Screenshot 2024-05-25 at 9.32.47 PM.png

Quentin
Super User

Macro variables will not resolve inside of single quotes.  So change:

 

variable='&selected_var'; 

to:

variable="&selected_var"; 

and be sure to do the same for the quoted strings on your IF statements as well.

Stanley3
Obsidian | Level 7

Thank you so much!! It runs great now

ballardw
Super User

Since your macro code is incomplete (missing and %end; and %mend; at the very least) we can't test your code.

 

Set

options mprint;

before running the macro. The LOG will show much more detail of the generated code.

 

Agree you have the wrong variable on the model statement.

Stanley3
Obsidian | Level 7

Thank you, this is life-changing!!

 

Quentin
Super User

@Astounding  already gave the correct answer.  This is a nice example of why @ballardw's point of turning on the MPRINT option is critical to understanding errors that are generated by a macro.  There is nothing worse than having MPRINT turned off, and having an error in your log, and no idea what code is causing the error.  I think MPRINT should always be turned on.  I know some people like to turn off MPRINT (and even NOTES) sometimes in production code that they "know" works and this saves them from having a big log file, or speeds up the code some tiny amount because it doesn't have to write a big log file.  I was the taught that the value of having a useful log file far outweighs any benefits that come from having a small log file.

 

In this case, when you turn on MPRINT, you should see that your code is generating a MODEL statement like:

model ln_bmi_medians ln_waist_median_cm ln_waist_hip_median = brinda15 / type3 dist=normal ;

And that makes clear that you intended to have only one dependent variable on the MODEL statement, but have accidentally listed all three.

Stanley3
Obsidian | Level 7
Thank you so much! I was not aware of the mprint option. I'll make sure to turn it on from now on.