MACRO

Accepted Solution Solved
Reply
New Contributor
Posts: 4
Accepted Solution

MACRO

Dear all,

 

I wanted to set up a macro to run quite a few logistic regression models. My question is how to I code it in such a way that

for the first 10 models, the macro would use bi as the dependent variable, for the next 10 models, use bi2 as the dependent variable etc.

The codes highlighted in purple wouldnt work.

 

%MACRO a;

%IF 1 <= &i <= 10 %THEN %DO; %LET &dep = bi; %END;

%IF 11 <= &i <= 20 %THEN %DO; %LET &dep = bi2; %END;

%IF 21 <= &i <= 30 %THEN %DO; %LET &dep = bi3; %END;

 

PROC LOGISTIC DATA = x;

MODEL &dep (REF = "Yes")= &indep;

RUN;

%MEND a;

%a(indep = mde, i = 1)

%a (indep = pds, i = 2)

%a (indep = pts, i = 3)

%a (indep = so, i = 4)

%a (indep = sp, i = 5)

:

%a(indep = pe, i = 30)

 

Any input is much appreciated. Thanks!


Accepted Solutions
Solution
‎01-25-2017 01:01 AM
Super Contributor
Posts: 251

Re: MACRO

I can see several problems there.

  • You haven't defined the parameters in your macro definition - calling the macro with them when they haven't been defined will cause an error
  • The if condition doesn't work like that for macro code, sadly; you have to expand it
  • The way you're referring to dep is wrong - you're referring to the value of dep, not to the macro variable itself.

 

Try it like this:

%MACRO a(indep=, i=);
%if %eval(&i >= 1 and &i <= 10)
    %then %let dep = bi;
    %else %if %eval(&i >= 11 and &i <= 20)
    %then %let dep = bi2;
    %else %if %eval(&i >= 21 and &i <= 30)
    %then %let dep = bi3;
PROC LOGISTIC DATA = x;
MODEL &dep (REF = "Yes")= &indep;
RUN;
%MEND a;

The %eval isn't strictly necessary, but I always use it - it tends to pick up typing mistakes faster that I inevitably introduce to my code! I also like to use %else like this, where the conditions are mutually exclusive; sadly macro code doesn't have a %select statement. (Indentation like this not obligatory, of course…)

View solution in original post


All Replies
Super User
Super User
Posts: 6,330

Re: MACRO

[ Edited ]

The %IF statement, really the implied %EVAL() function call, will not convert 

A <= B <= C

into

(A<=B) and (B<=C)

like the IF statement will.   

So you need to do that yourself.

Solution
‎01-25-2017 01:01 AM
Super Contributor
Posts: 251

Re: MACRO

I can see several problems there.

  • You haven't defined the parameters in your macro definition - calling the macro with them when they haven't been defined will cause an error
  • The if condition doesn't work like that for macro code, sadly; you have to expand it
  • The way you're referring to dep is wrong - you're referring to the value of dep, not to the macro variable itself.

 

Try it like this:

%MACRO a(indep=, i=);
%if %eval(&i >= 1 and &i <= 10)
    %then %let dep = bi;
    %else %if %eval(&i >= 11 and &i <= 20)
    %then %let dep = bi2;
    %else %if %eval(&i >= 21 and &i <= 30)
    %then %let dep = bi3;
PROC LOGISTIC DATA = x;
MODEL &dep (REF = "Yes")= &indep;
RUN;
%MEND a;

The %eval isn't strictly necessary, but I always use it - it tends to pick up typing mistakes faster that I inevitably introduce to my code! I also like to use %else like this, where the conditions are mutually exclusive; sadly macro code doesn't have a %select statement. (Indentation like this not obligatory, of course…)

Respected Advisor
Posts: 4,973

Re: MACRO

Since you have control of &i as a parameter, you don't really need to safeguard against unusual values.  You could simplify this to:

 

%if &i <= 10 %then %let dep = bi;

%else %if &i <= 20 then %let dep = bi2;

%else %let dep = bi3;

 

It's remotely possibly that the original %LET statements were correct.  More likely, the %LET statements should assign a value to DEP (as illustrated above), not to &DEP (as in your original code).

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 3 replies
  • 153 views
  • 3 likes
  • 4 in conversation