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

I need to run over 30 univariate logistic regression models.  I want to make these codes using macro but whatever I do, it didn't produce the summary.  Can someone please help me?

 

Non-macro code:

 

ods output OddsRatios = odds1;
 ods output ParameterEstimates = param1;
 
       proc logistic data=base;
                class sexc / param=ref ref=first;
                model revasc6m (event='1') = sexc;
            run;
 
 ods output OddsRatios = odds2;
 ods output ParameterEstimates = param2;
 
       proc logistic data=base;
                class ethnicityc / param=ref ref=first;
                model revasc6m (event='1') = ethnicityc;
            run;
 
 ods output OddsRatios = odds3;
 ods output ParameterEstimates = param3;
 
       proc logistic data=base;
               model revasc6m (event='1') = age;
            run;
 
 ods output OddsRatios = odds4;
 ods output ParameterEstimates = param4;
 
       proc logistic data=base;
               model revasc6m (event='1') = bmi;
            run;
 
  data combined_OR;
   set odds1 odds2 odds3 odds4;
   run;
 
  data combined_PA;
   set param1 param2 param3 param4;
   run;
 
Macro code I tried (the output file _null_ has 0 case) :


%macro univariate_logistic(data=, event=, vars=, class_vars=);


/* Create a temporary table to store results */

data _null_;
length var_name $20;
run;


/* Check if there are any class variables */
%let has_class_vars = %length(&class_vars);
%if &has_class_vars > 0 %then %do;

/* Run logistic regression for categorical variables */
%do i = 1 %to %sysfunc(countw(&class_vars));
%let var = %scan(&class_vars, &i);
proc logistic data=&data;
class &var / param=ref ref=last;
model &event (event='1') = &var;
run;
%end;
%end;

/* Run logistic regression for continuous variables */
%do i = 1 %to %sysfunc(countw(&vars));
%let var = %scan(&vars, &i);
proc logistic data=&data;
model &event (event='1') = &var;
run;
%end;

/* Append results to temporary table */

data _null_;
set _null_;
var_name = &var;
output;
run;

%end;

/* Output final results table */

proc print data=_null_;
run;

%mend;


%univariate_logistic(data=base, event=revasc6m, vars=age bmi ,
class_vars= sexc ethnicityc );

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

Hello @J_Park,

 

As a rule, a DATA step of the form

data _null_;
...
run;

does not create an output dataset. So, using _null_ later in a SET or PROC PRINT statement doesn't make sense as there is nothing to read.

 

Your non-macro code uses ODS OUTPUT statements. You can use them in your macro, too. Just insert

ods output OddsRatios(persist=proc) = odds;
ods output ParameterEstimates(persist=proc) = param;

at the beginning of the macro (after the %MACRO statement) and

ods output close;

at the end (before the %MEND statement). As a result, datasets ODDS and PARAM will contain the concatenated OddsRatios and ParameterEstimates outputs, respectively.

 

Also, consider using a %LOCAL statement in your macro (before the first %LET statement) to avoid unwanted side effects on macro variables outside of your macro:

%local has_class_vars i var;

View solution in original post

10 REPLIES 10
Amir
PROC Star

Hi,

 

Thanks for providing the code. When you say "it didn't produce the summary", do you mean there was no output, or there was an issue in the log, or the output was incorrect, etc? Please clarify what you received vs what you want.

 

Please try adding the following macro diagnostic statement before you invoke the macro again and post the log using the Insert Code icon "</>":

 

options mprint symbolgen;

 

 

 

Thanks & kind regards,

Amir.

J_Park
Obsidian | Level 7
Hello,
The typical sas results are there but the final result "proc print data=_null_;" was not created.

This is the error message I got:
2828 /* Append results to temporary table */
2829
2830 data _null_;
2831 set _null_;
2832 var_name = &var;
2833 output;
2834 run;
2835
2836 %end;
ERROR: There is no matching %DO statement for the %END. This statement will be ignored.

Also it says: NOTE: Variable var_name is uninitialized.
PaigeMiller
Diamond | Level 26

@J_Park wrote:

2836 %end;
ERROR: There is no matching %DO statement for the %END. This statement will be ignored.

So what %DO is this %END associated with? I don't see one, and SAS doesn't see one either

 

Your lack of output is explained by @FreelanceReinh above.

--
Paige Miller
FreelanceReinh
Jade | Level 19

@J_Park wrote:
ERROR: There is no matching %DO statement for the %END. This statement will be ignored.

Delete the duplicate %END statement.

%end;
%end;

The %END statement of the outer %DO-%END block is already there, further below. Proper code indentation will make this clearly visible.

PaigeMiller
Diamond | Level 26

@FreelanceReinh wrote:

@J_Park wrote:
ERROR: There is no matching %DO statement for the %END. This statement will be ignored.

Delete the duplicate %END statement.

%end;
%end;

The %END statement of the outer %DO-%END block is already there, further below. Proper code indentation will make this clearly visible.


I don't think that's it

 

%let has_class_vars = %length(&class_vars);
%if &has_class_vars > 0 %then %do;

/* Run logistic regression for categorical variables */
%do i = 1 %to %sysfunc(countw(&class_vars));
%let var = %scan(&class_vars, &i);
proc logistic data=&data;
class &var / param=ref ref=last;
model &event (event='1') = &var;
run;
%end;
%end;

There are two %DO and %END in this part of the code. The green %DO matches the green %END and the red %DO matches the red %END.

--
Paige Miller
FreelanceReinh
Jade | Level 19

Oh yes, you're right, of course. The extraneous %END to be deleted is the one "further below" (between the nonsensical steps which are to be deleted as well).

J_Park
Obsidian | Level 7

I got this message:

MPRINT(UNIVARIATE_LOGISTIC): data _null_;
MPRINT(UNIVARIATE_LOGISTIC): set _null_;
SYMBOLGEN: Macro variable VAR resolves to bmi
MPRINT(UNIVARIATE_LOGISTIC): var_name = bmi;
MPRINT(UNIVARIATE_LOGISTIC): output;
MPRINT(UNIVARIATE_LOGISTIC): run;

NOTE: Variable bmi is uninitialized.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds


MPRINT(UNIVARIATE_LOGISTIC): proc print data=_null_;
MPRINT(UNIVARIATE_LOGISTIC): run;

NOTE: No variables in data set WORK._NULL_.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

 

PaigeMiller
Diamond | Level 26

@J_Park wrote:

I got this message:

MPRINT(UNIVARIATE_LOGISTIC): data _null_;
MPRINT(UNIVARIATE_LOGISTIC): set _null_;
SYMBOLGEN: Macro variable VAR resolves to bmi
MPRINT(UNIVARIATE_LOGISTIC): var_name = bmi;
MPRINT(UNIVARIATE_LOGISTIC): output;
MPRINT(UNIVARIATE_LOGISTIC): run;

NOTE: Variable bmi is uninitialized.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds


MPRINT(UNIVARIATE_LOGISTIC): proc print data=_null_;
MPRINT(UNIVARIATE_LOGISTIC): run;

NOTE: No variables in data set WORK._NULL_.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

 


From now on, please provide logs in the "Insert Code" window (the </> icon), like this

 

MPRINT(UNIVARIATE_LOGISTIC): data _null_;
MPRINT(UNIVARIATE_LOGISTIC): set _null_;
SYMBOLGEN: Macro variable VAR resolves to bmi
MPRINT(UNIVARIATE_LOGISTIC): var_name = bmi;
MPRINT(UNIVARIATE_LOGISTIC): output;
MPRINT(UNIVARIATE_LOGISTIC): run;

NOTE: Variable bmi is uninitialized.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds


MPRINT(UNIVARIATE_LOGISTIC): proc print data=_null_;
MPRINT(UNIVARIATE_LOGISTIC): run;

NOTE: No variables in data set WORK._NULL_.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

 

 

So, this is telling you that the variable BMI does not have a value. Why? Because as stated above by @FreelanceReinh there is NO DATA in a data set named _NULL_. You have to give some other name to this data set in order for data to be saved and used later in the program.

--
Paige Miller
FreelanceReinh
Jade | Level 19

Hello @J_Park,

 

As a rule, a DATA step of the form

data _null_;
...
run;

does not create an output dataset. So, using _null_ later in a SET or PROC PRINT statement doesn't make sense as there is nothing to read.

 

Your non-macro code uses ODS OUTPUT statements. You can use them in your macro, too. Just insert

ods output OddsRatios(persist=proc) = odds;
ods output ParameterEstimates(persist=proc) = param;

at the beginning of the macro (after the %MACRO statement) and

ods output close;

at the end (before the %MEND statement). As a result, datasets ODDS and PARAM will contain the concatenated OddsRatios and ParameterEstimates outputs, respectively.

 

Also, consider using a %LOCAL statement in your macro (before the first %LET statement) to avoid unwanted side effects on macro variables outside of your macro:

%local has_class_vars i var;
J_Park
Obsidian | Level 7

Hello FreelanceReinh!

Your suggestion worked!!!!   Amazing!   I spent the whole day to try to figure this out.   

Thank you so much!   I really appreciate your help.

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
  • 10 replies
  • 1781 views
  • 2 likes
  • 4 in conversation