BookmarkSubscribeRSS Feed
model_coder
Calcite | Level 5
Is it possible to call IRR function from IML?
5 REPLIES 5
Rick_SAS
SAS Super FREQ
Yes, you can.

I'll present a general technique for writing a module that "wraps" a Base SAS function so that it becomes "vectorized." (This technique is adapted from code that will appear in my forthcoming book Statistical Programming with SAS/IML Software: An Introduction, SAS Press, 2010.)

The issue, for those not familiar with calling Base SAS functions, is that some Base SAS functions string out their arguments in a list, whereas in SAS/IML it is convenient to be able to pass a vector of values. For the case of the IRR function, you can call IRR from IML explicitly by forming a list:

proc iml;
/* call Base SAS function directly to find the answer */
rate1 = IRR(1,-400,100,200,300);
print rate1;

However, in SAS/IML the parameters are typically in a vector such as
c = {-400,100,200,300};
and you cannot call IRR as
rate2 = IRR(1,c); /* WRONG! Can't send vector to function expecting a list */

How can we call the Base SAS function? The key is to define a module that uses the PUTN function to convert the numeric parameters to a long, comma, separated list, then call the EXECUTE subroutine.

/* Call the IRR function in Base SAS.
This technique works for any Base SAS function that
is expecting a list of arguments instead of a vector.
Rick Wicklin */
start myIRR(freq, c);
/* convert numeric matrices a single string */
args = strip(putn(freq,"BEST12.")); /* string of the freq value */
cc = strip(putn(c, "BEST12.")); /* character vector of c */
do i = 1 to nrow(cc)*ncol(cc); /* concatenate all values */
args = concat(args, ",", strip(cc));
end;
cmd = "rate = IRR(" + args + ");" ; /* Base function call, as a string */
call execute(cmd); /* execute the string */
return (rate); /* return result from Base SAS function */
finish;

freq = 1;
c = {-400,100,200,300};
rate = myIRR(freq,c); /* call Base SAS function with vector */
print rate;
model_coder
Calcite | Level 5
Thanks Rick. This was very helpful.
model_coder
Calcite | Level 5
I have it working now after a small fix in the code. Message was edited by: model_coder
Rick_SAS
SAS Super FREQ
As model_coder mentions, there is a typo in the program.
The statement inside the DO loop should say:
args = concat(args, ",", strip(cc));
Rick_SAS
SAS Super FREQ
Rats: The blog software seems to "eat" certain character sequences. Very annoying.
The statement inside the DO loop should say:
args = concat(args, ",", strip(cc [ i ])); /* LEFT_BRACKET i RIGHT_BRACKET */

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

Register now!

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 5 replies
  • 2590 views
  • 1 like
  • 2 in conversation