BookmarkSubscribeRSS Feed
dad316
Calcite | Level 5

Hi All!

 

The below macro will conditionally set the macro variables &r1 and &r2 to either 0 or 1 based on the following criteria, where &sub. is a random number (which was generated by another macro variable).

if &sub. is a whole number  then r1=0 and r2 = 0

if &sub. has a decimal that rounds down then r1 = 1 and r2 = 0

if &sub. has a decimal around rounds up then r1 =1 and r2=1

 

However, i can't get the macro to work. When i use this macro i get the error message "Statement is not valid or is used out of proper order". Any tips?

 

%macro round_test (sub);
%let r1 = x;
%let r2 = y;
%let round = %eval(%sysfunc(int(&sub.))-&sub.);
%if &round = 0 %then %do;
          x=0;
          y=0;
%end;
%else %if round(&round) = 0 %then %do;
          x=1;
          y=0;
%end;
%else %do;
         x=1;
         y=1;
%end;
run;
%mend;

 

Hey Guys, I beleive i solved this with the below code:

 

%macro round_test (sub);
%let round = %eval(%sysfunc(int(&sub.))-&sub.);
%if &round = 0 %then %do;
      %let r1=0;
      %let r2=0;
%end;
%else %if round(&round) = 0 %then %do;
     %let r1=1;
      %let r2=0;
%end;
%else %do;
      %let r1=1;
      %let r2=1;
%end;
run;
%mend;

2 REPLIES 2
Astounding
PROC Star

You are getting closer.  However, note that:

 

%EVAL cannot use decimal points, let alone decimal fractions.  Use %SYSEVALF instead if you want the math to be performed on decimal fractions.

 

Macro language does not understand the ROUND function.  Apply %SYSFUNC to the ROUND function, to let macro language execute the DATA step version of the function.

Tom
Super User Tom
Super User

Why are you manipulating floating point numbers in macro variables?  If you do then make sure to use %sysevalf() instead of the default %eval().

 

Looks like you want something like this.

Make sure to define ROUND, R1 or R2 before you call the macro if you want to use the value after the macro ends.

%macro round_test (sub);
%local sign ;
%let round = %sysfunc(round(&sub));
%let sign = %sysfunc(sign(&round-&sub));
%let r1=%eval(&sign^=0);
%let r2=%eval(&sign=1);
%put &=sub &=round &=sign &=r1 &=r2 ;
%mend;
518  %round_test(1);
SUB=1 ROUND=1 SIGN=0 R1=0 R2=0
519  %round_test(1.1);
SUB=1.1 ROUND=1 SIGN=-1 R1=1 R2=0
520  %round_test(1.9);
SUB=1.9 ROUND=2 SIGN=1 R1=1 R2=1

 If you are going to use it on negative numbers then test those also to make sure if does what you want in that case.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 2 replies
  • 615 views
  • 0 likes
  • 3 in conversation