I am trying to write this macro to calculate the hand value of cards, however I keep getting the below error. Any suggestions?
%macro handValue(cards=);
proc iml;
use &cards;
read all into cards;
value = cards[ ,+];
%do i = 1 %to ncol(&cards);
%if(cards[i] = 1 & value <= 11) %then %do;
value = value + 10;
print value;
%end;
%end;
%if(value > 21) %then print 0;
%else %if(value = 21 & ncol(cards) = 2) %then print 21.5;
%else print value;
quit;
%mend;
ERROR: Required operator not found in expression: nol(&cards)
ERROR: The %TO value of the %DO I loop is invalid.
ERROR: The macro HANDVALUE will stop executing.
Remember that the macro language writes SAS code. Because you have loops and subscripts in the SAS/IML language you ALMOST NEVER need to use macro %DO loops. You can write this in straight IML.
I think there are logical problems with your code, but that is to be expected since you haven't been able to run/debug it. Rather than trying to figure out what you are trying to do, here is some code that runs that you can then debug:
proc iml;
use &cards;
read all into cards;
close &cards;
value = cards[ ,+];
print cards value;
do i = 1 to ncol(cards); /* OR nrow(cards) ?? */
if(cards[i] = 1 & value <= 11) then do;
value = value + 10;
print value;
end;
end;
if(value > 21) then print 0;
else if(value = 21 & ncol(cards) = 2) then /* or nrow(cards)??? */
print 21.5;
else print value;
One thing for you to think about: is the 'cards' variable a row vector, a column vector, or a matrix (each row of which is a hand)? If it is a matrix, then cards[i] is not going to make sense.
When I run this code:
proc iml;
use test_cards;
read all into cards;
value = cards[,+];
do i = 1 to ncol(cards);
if(cards[i] = 1 & value <= 11) then do;
value = value + 10;
print value;
end;
end;
if(value > 21) then print 0;
else if(value = 21 & ncol(cards) = 2) then print 21.5;
else print value;
quit;
the program works.
However I need it to be in a macro because I need to be able to put in any hand of cards and compute the value.
That's fine. Lots of people embed SAS/IML in a macro to pass in parameters such as data set names. My point is that you don't need %DO and %IF statements.
%macro handValue(cards=);
proc iml;
use &cards;
...
%mend;
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 to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.