One of the fundamental principles of computer programming is to break a task into smaller subtasks and to modularize the program by encapsulating each subtask into its own function. I have written many blog posts over the years about how to define and use functions in the SAS/IML language. I thought it would be useful to compile that information in a single place so that SAS/IML programmers can find it easily.
I will periodically add material to this post so that it remains current.
A simple example
The purpose of SAS/IML software is to enable you to extend the capabilities of SAS software. Creating user-defined modules is an important part of that purpose. Suppose that you want to define a new function that squares each element of a matrix. The following statements define the function Sqr and call the function with a vector parameter:
proc iml; /* square each element of a matrix */ start Sqr(x); return( x#x ); /* elementwise multiplication */ finish; x = 1:5; /* x = {1 2 3 4 5} */ y = Sqr(x); /* square each element: y = {1 4 9 16 25} */ |
How to define and use SAS/IML function modules
The following list contains fundamental information about creating SAS/IML functions.
- It's easy to define a new function in SAS/IML software. Use the START statement to specify the function name and arguments, write the body of the function, and use the FINISH statement to signal that the definition is complete.
- The parameters to a SAS/IML function are passed by reference, which means that their values can be modified from within the body of the function.
- There are two kinds of modules in the SAS/IML language: functions and subroutines. Functions use the RETURN statement to return a value. Subroutines do not return a value. They typically make modifications to the arguments (for example, sorting a vector), although you can also use subroutines to return multiple arguments from a module.
- Traditionally, the arguments to a user-defined module are matrices and the module returns the results in one or more matrices. Alternatively, you can pack the arguments into a SAS/IML list and send the list to the module. Similarly, you can pack many results into a list and return it as an output argument.
How to save, reuse, and share SAS/IML functions
An advantage of writing a module is that you can call the same function from several programs.
- You can store and load SAS/IML modules.
- After you have created several functions, you might want to create a library of functions. With one statement you can load all the functions in the library.
- In SAS/IML 14.1 you can use packages to share functionality. If you want to share with others, you can create a package.
Optional parameters and default values
SAS/IML 12.1 and 12.3 introduced optional parameters and default values for parameters.
- You can assign default values for optional parameters.
- You can specify that certain function parameters are optional but have no default values.
- You can use the ISSKIPPED function to detect which optional parameters are skipped.
- For subroutines, you can specify optional arguments by using keyword-value pairs.
- You can use the PARENTNAME function to discover the name of the variable that was passed into a function.
- You can iterate over all arguments to a module and process each in turn.
Scope of functions and variables
The following list provides technical details about how modules work.
- All modules are global in scope. The SAS/IML language does not support "hidden modules" or "local modules" or "nested modules."
- However, the SAS/IML language does support local and global variables. By default, all variables are local to a function. You can use the GLOBAL clause on the START statement to specify that certain variables are global. This is necessary for certain problems, including numerical integration, numerical root finding, and optimization problems.
- You can define a user-defined subroutine that has the same name as a built-in SAS/IML subroutine. Because of this, it is a good programming practice to use the RUN statement to run user-defined subroutines, and use the CALL statement to run built-in subroutines.
Debugging tips
- If your user-defined function detects a serious error, such as a missing data set, you can use the STOP statement to abort the computation.
- If the SAS log displays the message NOTE: Paused in module NAME, it usually means that a run-time error occurred in the module. You can use the RESUME statement or the ABORT statement to handle the error or return to the calling environment.
- Be aware that expressions like x+y and x[,1] create temporary matrices, so don't use expressions as parameters to subroutines that modify their arguments.
3 Comments
Dear Rick, can you give me an example of storing a module within Viya context?
It's exactly the same syntax as for PROC IML. Use the STORE statement.
Pingback: On passing a list to a SAS/IML module - The DO Loop