I have the following Macro code:
%macro LTV_DSCR(file1,file2,var,bins,lm1,lm2,rounding);
%local i j part1 part2;
%let i=1;
%do %while(%scan(%str(&file1), &i) ne);
%let part1=%scan(%str(%&file1), &i);
%let j=1;
%do %while(%scan(%str(%&file2), &j) ne);
%let part2=%scan(%str(%&file2), &j);
..........
%let j=%eval(&j+1);
%end;
%let i=%eval(&i+1);
%end;
%mend LTV_DSCR;
%LTVDSCR(RT OR OF IN MF LO, W SE SW MW NE, LTV, 10, 2.5, 4, 0.1);
The code gives error message:
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
%scan(&file1, &i) ne
ERROR: The condition in the %DO %WHILE loop, %scan(&file1, &i) ne, yielded an invalid or missing value, . The macro will stop
executing.
ERROR: The macro LTV_DSCR will stop executing.
This only happens when it reaches word like "OR" "NA".
How should I modify my code?
Yes, those are reserved words in SAS Macro language, ie OR is logical operator OR, not Oregon as you're likely using it.
See if these help you out:
https://blogs.sas.com/content/sgf/2014/08/15/macro-quoting-made-easy/
Hi, I tried most macro function suggested in the article, and none works. Can someone be more specific about how to resolve this issue?
Thanks.
Actually, you omitted the code that is causing the problem. It's likely that you can switch from %SCAN to %QSCAN to solve the problem but we may need to see the code indicated by "............"
The link given specifically shows what to do with OR
If it doesn't work, show us what you tried.
Make sure you catch all the problematic words, in this case likely:
OR, OF, NE at minimum.
It helps if you turn on MPRINT/SYMBOLGEN to see issues in the log and it identifies the problematic portion in more detail.
Replace that macro code with data step code, and it will be a lot easier.
First, wrap the ....... code into its own macro:
%macro do_single(part1,part2,var,bins,lm1,lm2,rounding);
........
%mend;
Then restructure your outer macro:
%macro LTV_DSCR(file1,file2,var,bins,lm1,lm2,rounding);
data _null_;
do i = 1 to countw("&file1", ' ');
part1 = scan("&file1",i,' ');
do j = 1 to countw("&file2",' ');
part2 = scan("&file2",j,' ');
call execute('%nrstr(%do_single(' !! trim(part1) !! ',' !! trim(part2) !! ",&var,&bins,&lm1,&lm2,&rounding))");
end;
end;
run;
%mend LTV_DSCR;
For the data step, there is no reason to consider anything in a string a "special word" that needs to be masked.
See this simple example:
%macro do_single(part1,part2,var,bins,lm1,lm2,rounding);
%put &part1;
%put &part2;
%put &rounding;
%mend;
%macro LTV_DSCR(file1,file2,var,bins,lm1,lm2,rounding);
data _null_;
do i = 1 to countw("&file1", ' ');
part1 = scan("&file1",i,' ');
do j = 1 to countw("&file2",' ');
part2 = scan("&file2",j,' ');
call execute('%nrstr(%do_single(' !! trim(part1) !! ',' !! trim(part2) !! ",&var,&bins,&lm1,&lm2,&rounding))");
end;
end;
run;
%mend LTV_DSCR;
%LTV_DSCR(RT OR OF IN MF LO, W SE SW MW NE, LTV, 10, 2.5, 4, 0.1);
Abbreviated log from that:
45 %LTV_DSCR(RT OR OF IN MF LO, W SE SW MW NE, LTV, 10, 2.5, 4, 0.1); NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds NOTE: CALL EXECUTE generated line. 1 + %do_single(RT,W,LTV,10,2.5,4,0.1) RT W 0.1 2 + %do_single(RT,SE,LTV,10,2.5,4,0.1) RT SE 0.1
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.