BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
apple
Calcite | Level 5

Using SAS EG 7.1.

 

How do I resolve the below? THank you

 

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

A AND B

 

CODE:

 

%DO YEAR=&FIRSTYR %TO &LASTYR;

 

%do i = 1 %to %sysfunc(countw(&monlist.));

%let month = %sysfunc(putn(%scan(&monlist.,&i.),z2.)); /*i is numeric; whereas &MONTH is char (01,02,etc). So convert numeric i to char &MONTH.*/

PROC SORT DATA =CN; BY ID Date; RUN;

PROC SORT DATA = Tax&YEAR.&MONTH; BY ID Date ; RUN;

DATA TaxCN&YEAR.&MONTH;

MERGE Tax&YEAR.&MONTH(IN=A) CN(IN=B);

BY ID Date;

%IF A AND B %THEN MERGEID='1';%ELSE

%IF A AND NOT B %THEN MERGEID='2';%ELSE

%DO; MERGEID='4';%END;

RUN;

DATA FA&YEAR.&MONTH_CN (drop=MERGEID);

set FA&YEAR.&MONTH_CN;

IF MERGEID='2' Or MERGEID='1';

RUN;

PROC SORT DATA =FACN&YEAR.&MONTH; BY UIN; RUN;

%END;

%END;

 

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

Macro language is used to dynamically create program text; it is dealt with long before a data step is executed.

Also, macro language ONLY knows the datatype character, but not numeric. Special functions need to be used for numeric operations, when necessary.

 

In your case,

%IF A AND B %THEN MERGEID='1';%ELSE
%IF A AND NOT B %THEN MERGEID='2';%ELSE
%DO; MERGEID='4';%END;

means that the macro engine, when it encounters the "and" operator, needs boolean values, but the texts "A" and "B" are not numbers. The numeric variables A and B will exist much later (during data step execution), when the macro has long before finished. The macro cannot know them.

If I read your intentions right, you just need to use the correct data step language at this point:

if A and B
then MERGEID = '1';
else if A and not B
then MERGEID = '2';
else MERGEID = '4';

View solution in original post

3 REPLIES 3
Kurt_Bremser
Super User

Macro language is used to dynamically create program text; it is dealt with long before a data step is executed.

Also, macro language ONLY knows the datatype character, but not numeric. Special functions need to be used for numeric operations, when necessary.

 

In your case,

%IF A AND B %THEN MERGEID='1';%ELSE
%IF A AND NOT B %THEN MERGEID='2';%ELSE
%DO; MERGEID='4';%END;

means that the macro engine, when it encounters the "and" operator, needs boolean values, but the texts "A" and "B" are not numbers. The numeric variables A and B will exist much later (during data step execution), when the macro has long before finished. The macro cannot know them.

If I read your intentions right, you just need to use the correct data step language at this point:

if A and B
then MERGEID = '1';
else if A and not B
then MERGEID = '2';
else MERGEID = '4';
pawan
Obsidian | Level 7

Try converting the "i" value into Char by removing trailing blanks. I think that should be the issue and give a try something like below

%do i = 1 %to %sysfunc(trim(left(put((countw(&monlist.)),best.));

RW9
Diamond | Level 26 RW9
Diamond | Level 26

A far simpler methodology, and one which should be on the first page of every learning manual, is data structure.  You are finding that your life is difficult because of one simple fact, you have put "data" into an area which is not designed to hold "data".  Dataset names, column names, these are here for the purpose of making programming simpler and more efficient, they are Not designed to hold "data".  Column labels, and observations are designed to hold data.  

 

The reason I point this out is that by a simple structure change to your data, you can eliminate all that code, and write simple basic efficient and easy to maintain Base SAS code, which will do exactly the same purpose.  Where you have datasets called taxYYYYMM, create one dataset, which has all the data, with columns for YYYY and MM:

data tax201502;
  a=1; output;
run;
data tax201503;
  a=2; output;
run;
data tax;
  set work.tax: indsname=nme;
  year=input(substr(scan(nme,2,"."),4,4),4.);
  month=input(substr(scan(nme,2,"."),8,2),2.);
run;

Now you have one dataset with all your data in one place.  You can manipulate this one dataset using simple basic datasteps, no need for looping or macros or any other complicated code.  And if for some reason you need to split them up again later on, then that again is a simple datastep output routine.  Remember the data structure is there for your benefit.

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
  • 3 replies
  • 1240 views
  • 4 likes
  • 4 in conversation