BookmarkSubscribeRSS Feed
ejohnson96
Calcite | Level 5

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.

3 REPLIES 3
Rick_SAS
SAS Super FREQ

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.

ejohnson96
Calcite | Level 5

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. 

Rick_SAS
SAS Super FREQ

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: Register Now

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!

Multiple Linear Regression in SAS

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.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 3 replies
  • 1607 views
  • 0 likes
  • 2 in conversation