Desktop productivity for business analysts and programmers

Defining macro variable by cases

Accepted Solution Solved
Reply
Contributor
Posts: 46
Accepted Solution

Defining macro variable by cases

I'm on SAS EG 5.1.

 

One possible way to define variables by cases is, for instance,

Variable=2*(Statement 1)+3*(Neg of Statement 1);

What is this called? I'd like to read about it, but I don't know what words to search for.

 

 

Now please consider the following code.

 

%MACRO CYCLE;
	%DO A=1 %TO 2;
	%PUT &A.;
	%LET B=0.636805089257504*(&A.=1)+0.656423671305948*(&A.=2);
	%PUT &B.;
	%END;
%MEND; %CYCLE;

On the log I find this:

 

1
0.636805089257504*(1=1)+0.656423671305948*(1=2)
2
0.636805089257504*(2=1)+0.656423671305948*(2=2)

I expected it to be

 

1
0.636805089257504
2
0.656423671305948

What am I missing?

 

 

Finally, for my actual question, regarding the second block of code, I'm trying to sue the variable B within a Data-Step and it's obvious from some simple computations that B isn't getting the value I expected it to get. In fact, it gets a value that doesn't seem at all related with any of the coefficients used above.

 

I worked around this by defining B withing the Data-Step, but this is seems crass.

Can you explain to me why isn't my macro variable B working properly and how can I fix it?

 

Thanks.


Accepted Solutions
Solution
‎07-13-2016 02:10 PM
Contributor
Posts: 27

Re: Defining macro variable by cases

Hi,

 

If you are attempting to evaluate arithmetic expressions represented by values of macro variables, you need to use the macro function %SYSEVALF (http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000206831.htm)

 

 

Thank you,

 

John

View solution in original post


All Replies
Occasional Contributor
Posts: 19

Re: Defining macro variable by cases

Hi
All macro variables are character, there are no numeric variables.
If you want to perform a calculation use the %eval macro function, for example %eval(0.636805089257504*(&A.=1)+0.656423671305948*(&A.=2));
This should give you the expected results
Cheers
Chris
Contributor
Posts: 46

Re: Defining macro variable by cases

Apparently I need to use %SYSEVALF. Using %EVAL I get the following error.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
0.636805089257504*(1=1)+0.656423671305948*(1=2)
ERROR: The macro CYCLE will stop executing.
Super User
Posts: 19,171

Re: Defining macro variable by cases

1. This is logic, base math, and the fact that true/false are represented as 1/0. I don't know that that's documents anywhere but you could try searching for Boolean operators. 

2. If you want to evaluate an expression while assigning macro variables you need to use %eval and/or %sysevalf. One deals with integer arithmetic and the other with floating point arithmetic.

How is SAS supposed to know if you want that as text or if you want the expression resolved? By default it treats it as text and you can override this by using the macro functions mentioned above. 

Contributor
Posts: 46

Re: Defining macro variable by cases

Thanks.

 

I asked because I'm pretty sure I've read about it on the help documentation and I'd like to see what's on that article.

 

To me it's not obvious that a statement and its truth value are one and the same. In fact, being a mathematician, conceptually they are two different things and before you told me this it didn't cross my mind that it would all be the same for SAS.

 

I didn't know macro variables are text by default, thanks.

Super User
Posts: 11,134

Re: Defining macro variable by cases

[ Edited ]

Programming unfortunately is not mathematics as we get to deal with the "rules" established by the program designers.

 

Numeric to true and false work two slightly different ways.

When SAS assigns the value to a comparison it will always use 1 for true and 0 for false.

But if you have a numeric variable you can use it as a boolean. If the value is not missing and not 0 SAS will treat it as true, otherwise false.

Please see the results from this brief program as a demonstration.

data _null_;
   do x= -1 to 3, ., .5;
      if (x) then put x " is true";
      else put x " is false";
   end;
run;

 

Contributor
Posts: 46

Re: Defining macro variable by cases

Instructive. Thank you very much.

Super User
Posts: 19,171

Re: Defining macro variable by cases

You should check how SAS treats positive/negative/0 values. 

Which is true/false is good to know. 

Contributor
Posts: 46

Re: Defining macro variable by cases

I thought I had replied, I just noticed I didn't.

 

Thank you for this lesson.

Super User
Posts: 19,171

Re: Defining macro variable by cases

Solution
‎07-13-2016 02:10 PM
Contributor
Posts: 27

Re: Defining macro variable by cases

Hi,

 

If you are attempting to evaluate arithmetic expressions represented by values of macro variables, you need to use the macro function %SYSEVALF (http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000206831.htm)

 

 

Thank you,

 

John

Super User
Posts: 5,369

Re: Defining macro variable by cases

Even though it's good to understand the processes and how the macro processor works ...

 

Within a DATA step you are probably getting improper values because of the DATA step's order of operations.  When you substitute the very long version of &B in a DATA step, the order of operations is likely wrong.  A simple way to solve this is to add parentheses.  Instead of:

 

%let B= ...;

 

Use:

 

%let B=(...);

 

Just include the same logic as you are now but add parentheses.  That will force the DATA step to perform math on the longer expression first, before using it in further calculations.

Contributor
Posts: 46

Re: Defining macro variable by cases

Will do, thanks.

☑ This topic is solved.

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

Discussion stats
  • 12 replies
  • 612 views
  • 1 like
  • 6 in conversation