You can extend the capability of the SAS/IML language by writing modules. A module is a user-defined function. You can define a module by using the START and FINISH statements.
Many people, including myself, define modules at the top of the SAS/IML program in which they are used. You can do this explicitly or you can use the %INCLUDE statement.
An alternative is to store modules in a SAS catalog and to load the modules when you need to use them. As stated in the SAS/IML User's Guide:
Modules are stored in the form of their compiled code. Once modules are loaded, they do not need to be parsed again, making their use very efficient.
Storing modules
Storing a SAS/IML module requires two steps:
- Decide where the module will be stored.
- Store the module by using the STORE statement.
As an example of storing a module, consider the following module that finds the rows in a matrix for which all variables are nonmissing. This module is from my book, Statistical Programming with SAS/IML Software.
proc iml; /* create a module to return the nonmissing rows of a matrix */ start LocNonMissingRows(x); r = countmiss(x, "row"); /* 9.22 function: number missing in row */ nonMissingIdx = loc(r=0); /* rows that do not contain missing */ return ( nonMissingIdx ); finish; |
You can store the module in any SAS library such as SASUSER or a user-defined libref. Use the RESET STORAGE statement to set the name of a storage location. (By default, the module will be stored in the WORK library, which vanishes when you exit SAS!) The following statements set up a libref stores the module in a catalog called BlogModules:
libname BlogDir "C:\Users\userid\Documents\My SAS Files\Blog"; reset storage=BlogDir.BlogModules; /* set location for storage */ store module=LocNonMissingRows; |
In PROC IML, the STORE statement stores the LocNonMissingRows module in a SAS catalog in the BlogDir library. By using the RESET STORAGE, you ensure that the module is stored to a permanent location.
Loading modules
Similarly, suppose it is a few months later and you want to use the LocNonMissingRows module in a program that you are writing. You can use the RESET STORAGE statement and a LOAD statement to load the module definition:
proc iml; libname BlogDir "C:\Users\userid\Documents\My SAS Files\Blog"; reset storage=BlogDir.BlogModules; /* set location for storage */ load module=LocNonMissingRows; |
You can now use the module in your program to find all rows in a matrix for which no entry is a missing value:
z = {1 2, 3 ., 5 6, 7 8, . 10, 11 12}; nonMissing = LocNonMissingRows(z); if ncol(nonMissing)>0 then z = z[nonMissing, ]; print z; |
7 Comments
Pingback: An easy way to define a library of user-defined functions - The DO Loop
Ability to store the modules in a library helps in a big way when addressing complex problems with SAS/IML. I would prefer to load all the Modules that I use in an IML session. Does Load Module support loading multiple modules in a single statement? (Similarly does store allows us to store multiple modules at one go?) I am trying to organize my code into files (each with a proc iml) if that helps.
Yes, you can specify a list of modules in parentheses such as module=(Mod1 Mod2 Mod3).
You can also use the _ALL_ keyword to load all modules, as shown in the article
"An easy way to define a library of user-defined functions"
Can I load a module outside of proc IML?. For example, if I want to use it in the proc MCMC.
SAS/IML modules use matrix computations and functions that are not available in other SAS procedures, so you can't call an IML module from MCMC or the DATA step. For MCMC, you can define function in PROC FCMP, as shown in the MCMC documentation.
Pingback: Simulate data from a generalized Gaussian distribution - The DO Loop
Perfect, that works for me having saved the blogdir to a caslib.