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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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