BookmarkSubscribeRSS Feed
Tommer
Obsidian | Level 7

Hi, I am learning to work with %IF %THEN in macros and neither of my below codes are working. Could you please help me understand what is going here?

 

data cars3;
set cars;
%macro tr (M=);
    %if &M <30000 %then %do;
            profitlabel= "greater than 30000";
   %end;


%else %if &M>30000 %then %do;
       profitlabel = "Less than 30000";
%end;

%mend;
%tr (M=msrp);

run;

 

 

/* Above code did not work---all values are populated as "Less than 30000"*/

 

/* Below  code did not work---profitlabel is not created at all*/


data cars4;
set cars;
profit = msrp-invoice;

%macro msrp (T=, M=);
         %if &T = "&M" %then %do;
                 if profit>3000 then profitlabel= "greater than 3000";
               else profitlabel = "Less than 3000";
         %end;

%mend;


%msrp (T=Make,M=Acura);

run;

5 REPLIES 5
Tom
Super User Tom
Super User

Do not place macro definitions into the middle of a data step.  The macro processor will process the macro statements and generate text that is passed to SAS to evaluate. So the macro definition will be compiled (and your call to it will run) BEFORE that data step is compiled and so before the data step can start running.  Putting the macro definition into the middle of the data step will just confuse you.

 

You passed the macro the string msrp which you then compared to 30000.  The letter m comes after the digit 3 so the macro always generates this statement.

 profitlabel= "greater than 30000";

If you want to test the value of the variable MSRP you need your macro to generate an actual IF statement.  

So if you run this program:

%macro tr (M=);
if &M <30000 then do;
  profitlabel= "greater than 30000";
end;
else if &M>30000 %then do;
  profitlabel = "Less than 30000";
end;
%mend;

data cars3;
  set cars;
  %tr (M=msrp);
run;

It is the same as running this data step without the macro.

data cars3;
  set cars;
  if msrp <30000 then do;
    profitlabel= "greater than 30000";
  end;
  else if msrp>30000 %then do;
    profitlabel = "Less than 30000";
  end;
run;
Kurt_Bremser
Super User

Since the macro is resolved when code text is fetched for interpretation/compilation, it NEVER has access to the values of data step variables.

This macro

%macro tr (M=);
    %if &M <30000 %then %do;
            profitlabel= "greater than 30000";
   %end;
%else %if &M>30000 %then %do;
       profitlabel = "Less than 30000";
%end;
%mend;
%tr (M=msrp);

resolves macro variable &m to the text(!) msrp, so the condition turns into

%if msrp <30000 %then %do;

Since letters come after numbers in the ASCII character table, this condition resolves to false, and the following code is not created.

But the next condition is true, so the code from it is sent to the data step compiler, which now gets this code:

data cars3;
set cars;
       profitlabel = "Less than 30000";
run;

What you want for your first code is this:

%macro tr (M=);
if &M ge 30000
then profitlabel= "greater than 30000";
else profitlabel = "Less than 30000";
%mend;

data cars3;
set cars;
%tr (M=msrp);
run;

Similar issues happen with your second code.

Tommer
Obsidian | Level 7
@Kurt_Bremser @Tom thank you for your help! I am trying to learn how to use %if %then. Looks like the same can be achieved using if - then and macro variables. I could not find much documentation on %if %then in the advanced SAS certification prep guide for different scenarios to use %if %then. Could you by any chance point me in the right direction?
Kurt_Bremser
Super User

A simple rule of thumb:

%IF controls which code is created for the interpreter/compiler, while IF controls which part of the code (branch) is executed.

gamotte
Rhodochrosite | Level 12
Hello,

Macro language is used for dynamic code generation. Macros allow to reuse code without copying/pasting. When a macro program is executed, a first phase transforms macro code into base SAS language (which is executed in a second phase). Code enclosed with %if; ... %then; will be integrated to the final code when the condition is true and will be ignored otherwise.

For example, the program :

data have;
set sashelp.class;
%if 1 %then %do;
keep name;
%end;
%if 0 %then %do;
keep age;
%end;
run;

will become

data have;
set sashelp.class;
keep name;
run;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

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
  • 5 replies
  • 504 views
  • 0 likes
  • 4 in conversation