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-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 1290 views
  • 0 likes
  • 2 in conversation