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;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.