Why does null value of macro variable resolve as 0<&var<1?

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 17
Accepted Solution

Why does null value of macro variable resolve as 0<&var<1?

Hi everyone,

I'm perplexed by a situation I've encountered and I'm wondering if anyone can explain to me the inner SAS workings behind this.

I have a list of macros variables that I am scrolling through and subjecting to macro conditional logic. Something like this:

%let var1=0.1;

%let var2=0.5;

%let var3=1.5;

%let var4= ;

%let var5=0;

%macro q;

%if  0 < &&var&i < 1 %then %put &&var&i is between 0 and 1;

%else %put &&var&i is not between 0 and 1;

%mend q;

%q

My issue is this: the macro variable that is null (in this case, &var4) seems to resolve this condition as TRUE! This seems strange to me! I understand that a null value of a macro variable is not the same as a missing value of a data step variable, but I'm still not sure why this should resolve as being 0<var<1. I have tried other conditions, such as %IF &&VAR&I > 1 and these do NOT resolve as TRUE.

I have managed to get this code running fine using solutions to check for macro variables with null values prior to my conditional logic step, but my questions is WHY does &var4 resolve as being between 0 and 1? Can anyone explain to me the SAS workings behind this? Like I said, the code is working find with some work-arounds, but I am curious to know the reason behind it.

Thanks in advance for any insight you can provide!

Ashley


Accepted Solutions
Solution
‎08-23-2013 02:27 PM
Super User
Posts: 5,518

Re: Why does null value of macro variable resolve as 0<&var<1?

Posted in reply to ashlicole

Ashley,

There are two issues you will run into.  The first one explains the results for &VAR4.

%if &a < &b < & c %then %do;

In macro language, expressions resolve from left to right.  This statement operates as if you had added parentheses:

%if (&a < &b) < &c %then %do;

Macro makes the first comparison, and replaces true comparisons with 1 and false comparisons with 0.  In your case, when &VAR4 is null, null is less then 0 so the first comparison is false.  The second comparison then becomes:  0 < 1 which is, of course, true.

The second issue you will encounter has to do with decimal points.  When macro language makes comparisons, it applies the %EVAL function.  %EVAL interprets decimal points as character strings.  Thus this comparison would also be true:

%if 39 < 4.0 %then %do;

As others have noted, %SYSEVALF can perform decimal fraction arithmatic.  This comparison would be false:

%if %sysevalf (39 < 4.0) %then %do;

Good luck.

View solution in original post


All Replies
Super User
Posts: 19,878

Re: Why does null value of macro variable resolve as 0<&var<1?

Posted in reply to ashlicole

This

0 < &&var&i < 1

type of logic doesn't work in macro world, you need to specify it as 0 < &&var&i  and &&var&i < 1


There's an explanation of why somewhere on here but I don't recall Smiley Happy

I think it resolves as 0<null = false then false<1 which is true rather than as vari between 0 and 1. 

Respected Advisor
Posts: 3,156

Re: Why does null value of macro variable resolve as 0<&var<1?

Posted in reply to ashlicole

Be careful when to use "0 < &&var&i < 1 ", in Macro, it will be interpreted as 0 < (&&var&i < 1). So anything that is less then 1 will be true, including those negative numbers.  Instead, breaking it up seems to be the safer way:

&&var&i  >0 and &&var&i < 1 

Haikuo

Respected Advisor
Posts: 3,799

Re: Why does null value of macro variable resolve as 0<&var<1?

From the looks of those macro variable decimal values, I'm thinking you need to get %SYSEVALF involved.  Or better still don't use macro for this.

Respected Advisor
Posts: 3,156

Re: Why does null value of macro variable resolve as 0<&var<1?

Posted in reply to data_null__

Absolutely.

"You must use the %SYSEVALF function to evaluate logical expressions containing floating-point or missing values."

SAS(R) 9.2 Macro Language: Reference

Super Contributor
Posts: 307

Re: Why does null value of macro variable resolve as 0<&var<1?

Posted in reply to ashlicole

You could do something as follows:

data _null_;

format x 9.3 y $4. z $50.;

do i=1 to 5 ;

x = symget('var'||left(i));

y = 'var'||left(i);

if ( 0 < x < 1 ) then do ;

  z = y || " is between 0 and 1";

  put z;

end ;

else do ;

  z = y || " is not between 0 and 1";

  put z;

end;

output;

end ;

run;

Solution
‎08-23-2013 02:27 PM
Super User
Posts: 5,518

Re: Why does null value of macro variable resolve as 0<&var<1?

Posted in reply to ashlicole

Ashley,

There are two issues you will run into.  The first one explains the results for &VAR4.

%if &a < &b < & c %then %do;

In macro language, expressions resolve from left to right.  This statement operates as if you had added parentheses:

%if (&a < &b) < &c %then %do;

Macro makes the first comparison, and replaces true comparisons with 1 and false comparisons with 0.  In your case, when &VAR4 is null, null is less then 0 so the first comparison is false.  The second comparison then becomes:  0 < 1 which is, of course, true.

The second issue you will encounter has to do with decimal points.  When macro language makes comparisons, it applies the %EVAL function.  %EVAL interprets decimal points as character strings.  Thus this comparison would also be true:

%if 39 < 4.0 %then %do;

As others have noted, %SYSEVALF can perform decimal fraction arithmatic.  This comparison would be false:

%if %sysevalf (39 < 4.0) %then %do;

Good luck.

Respected Advisor
Posts: 3,156

Re: Why does null value of macro variable resolve as 0<&var<1?

Posted in reply to Astounding

Bravo for the correct answer!

Occasional Contributor
Posts: 17

Re: Why does null value of macro variable resolve as 0<&var<1?

Posted in reply to ashlicole

Thank you, Astounding, for putting this so eloquently! The left-to-right logic makes perfect sense to me and i can now see the problem with this comparison!

P.S. thanks to all for the %SYSEVALF tip as well... i had actually sort of simplified/anonymized my code to post this question and hence the code i listed would not actually have worked without %SYSEVALF, but my real code was fine (other than that darn null macro variable!). thank you regardless for the feedback on that too.

🔒 This topic is solved and locked.

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

Discussion stats
  • 8 replies
  • 335 views
  • 8 likes
  • 6 in conversation