BookmarkSubscribeRSS Feed
dht115
Calcite | Level 5

Hello, 

 

I am trying to create macro variable within if else condition. 

I am getting an error: 

 

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
2022-i

 

%LET year = 2022;
%LET qtr = 1;

data test;
do i = 1 to 5;
	do j = 1 to 4;
/*qtr is 1*/
/*when j = 1, prefer to run following if condition*/
		if &qtr.-j <= 0 then do;
/*			create macro variable CY (year - i value)*/
/*			create macro variable CQ (qtr - j = 4 value)*/
			%let CY = %eval(&year.-i);
			%let CQ = %eval(&qtr.-j+4);
			var(4*(i-1)+j) = (test&CY.&CQ.);
			end;

		else do;
			%let CY = %eval(&year.-(i-1));
			%let CQ = %eval(&qtr.-j);
			var(4*(i-1)+j) = (test&CY.&CQ.);
			end;
		end;
	end;
run;

2 REPLIES 2
PaigeMiller
Diamond | Level 26

The variable named i is a DATA step variable. The %EVAL function cannot operate on data step variables, it only accepts macro variables.

 

Whenever you write macro or macro variable code, you FIRST need to obtain working valid legal SAS code for one instance without macros and without macro variables. If you can't get the code to work without macros and without macro variables, it will never work with macros and with macro variables. In this case, your statement 

 

var(4*(i-1)+j) = (test&CY.&CQ.);

is not valid legal SAS code in this data step as written, even if you remove both macro variables, because the left hand side of the equation will cause an error. Also variables whose name begin with TEST are undefined.

 

You should probably re-write this entirely as DATA step code with no macros or macro variables. This can be done via ARRAYs in your DATA step. You should also re-write the code to use valid SAS date values to represent quarters, rather than developing your own arithmetic to obtain and manipulate quarters.

 

People usually ignore the advice to write working valid legal SAS code without macros first. But if you don't do that, I don't see how any progress can be made. Don't ignore the advice.

 

Here, I'll even do the easy part for you, this is your code without macros and without macro variables. Now, you make it into working valid legal SAS code that does what you want. (Becuase it doesn't work right now, and I have no idea what you are trying to do)

 

data test;
do i = 1 to 5;
	do j = 1 to 4;
		if 1-j <= 0 then do;
			CY = 2022.-i;
			CQ = 1-j+4;
			var(4*(i-1)+j) = (test20221);
			end;

		else do;
			CY = 2022-(i-1);
			CQ = 1-j;
			var(4*(i-1)+j) = (test20221);
			end;
		end;
	end;
run;

 

--
Paige Miller
Kurt_Bremser
Super User

Write this down and stick it to your monitor:

 

The macro PREprocessor does its work with code before that code is sent to the SAS interpreter.

 

So the %LET statements are resolved BEFORE your data step code is sent to the data step compiler, therefore your "inner" (which are, as you will see, not "in" the data step at all) %LETs are resolved with this:

%let CY = %eval(2022-i);
%let CQ = %eval(1-j+4);

Now, neither the letter i nor the letter j are numeric in any way, and that is why the macro preprocessor complains.

 

You can only create data step code with the macro processor, but you cannot use it (with the exception of data step functions in a %SYFUNC, but these are then also evaluated at macro resolve time, not at code execution time).

 

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