Chapter 5. IMLPlus: Programming in SAS/IML Studio

Contents

  • 5.1 Overview of the IMLPlus Language 109

  • 5.2 Calling SAS Procedures 111

    • 5.2.1 Passing Parameters to a SAS Procedure 111

    • 5.2.2 Checking the Return Code from a SAS Procedure 111

  • 5.3 Calling R Functions 112

  • 5.4 IMLPlus Graphs 112

  • 5.5 Managing Data in Memory 112

  • 5.6 Using Expressions When Reading or Writing Data 113

  • 5.7 IMLPlus Modules 114

    • 5.7.1 Storing and Loading IMLPlus Modules 114

    • 5.7.2 Local Variables in Modules 117

    • 5.7.3 Creating an Alias for a Module 117

  • 5.8 The IMLPlus Module Library 119

  • 5.9 Features for Debugging Programs 121

    • 5.9.1 Jumping to the Location of an Error 121

    • 5.9.2 Jumping to Errors in Modules 123

    • 5.9.3 Using the Auxiliary Input Window as a Debugging Aid 124

    • 5.9.4 Using the PAUSE Statement as a Debugging Aid 125

  • 5.10 Querying for User Input 126

  • 5.11 Differences between IMLPlus and the IML Procedure 126

5.1 Overview of the IMLPlus Language

The programming language of SAS/IML Studio is called IMLPlus. IMLPlus is an extension of SAS/IML that contains additional programming features. IMLPlus combines the flexibility of programming in the SAS/IML language with the power to call SAS procedures and to create and modify dynamically linked statistical graphics. Consequently, IMLPlus contains all of the capabilities of PROC IML that are described in earlier chapters, but it can also do much, much more.

This chapter describes statements and features of the IMLPlus language that are not supported in the IML procedure in SAS 9.2. You can use these features from the SAS/IML Studio environment, but not from PROC IML. Consequently, this chapter also answers the question, "What are the advantages to using SAS/IML Studio instead of PROC IML?"

Many of these features are described elsewhere in the book, but are collected and summarized here for easy reference. These IMLPlus statements and features enable you to use SAS/IML Studio to do the following:

  • Call SAS procedures from within IMLPlus and pass parameters to a SAS procedure from SAS/IML matrices

  • Call R functions from within IMLPlus

  • Create dynamically linked statistical graphs

  • Query, manipulate, and modify data that are stored in memory

  • Read and write data by using expressions for data set names

  • Define and use modules that are automatically loaded at run time, have local variables, and can be defined anywhere in the program

  • Dynamically define an alias for a module name

  • Access a rich library of modules, including dialog boxes that prompt for user input

  • Jump directly to the location of a programming error

  • Debug your program or interact with your data by using the PAUSE statement

Some IMLPlus features have proved to be very popular and so might be implemented in future releases of the IML procedure. For example, the 9.22 and 9.3 releases of SAS/IML software include a SUBMIT block for submitting SAS statements and for calling R functions from PROC IML.

When you run an IMLPlus program, you are implicitly "in IML," meaning that you do not need to use the PROC IML statement at the top of your program, nor do you need to end your program with the QUIT statement.

Although not required, the PROC IML and the QUIT statements are supported in IMLPlus. The PROC IML statement frees all matrices, clears user module definitions, closes any open data sets and files, and resets all SAS/IML options. The QUIT statement stops the execution of the program.

5.2 Calling SAS Procedures

A powerful feature in SAS/IML Studio is the ability to call SAS procedures from within an IMLPlus program. This enables your IMLPlus programs to compute and use any statistic available from any SAS procedure, any DATA step, and any macro program. You can call SAS procedures and DATA steps by writing SAS statements between a SUBMIT and an ENDSUBMIT statement. The SAS statements in between are called a SUBMIT block. The statements in the SUBMIT block are sent to the SAS System for execution.

This feature is described in Chapter 4, "Calling SAS Procedures."

You should also use the SUBMIT statement for global SAS statements such as the LIBNAME statement, the FILENAME statement, and the TITLE statement, the OPTIONS statement, and so on. In IMLPlus, global statements that are executed in a SUBMIT block also persist outside the SUBMIT block. For example, if you define a libref by using a LIBNAME statement inside a SUBMIT block, you can also use that libref in IMLPlus statements that are executed after the ENDSUBMIT statement.

5.2.1 Passing Parameters to a SAS Procedure

It is possible to pass parameters to a SAS procedure from SAS/IML matrices. In this way, you can specify names of variables, data sets, and options to the procedure. To pass the contents of a matrix to a SAS procedure, list the name of the matrix on the SUBMIT statement. Inside the SUBMIT block, refer to the contents of the matrix by preceding the name of the matrix with an ampersand (&). IMLPlus substitutes the values of the matrix (converted to a row vector, with spaces between consecutive elements) before sending the SUBMIT block to the SAS System for processing.

This feature is described in Chapter 4, "Calling SAS Procedures."

5.2.2 Checking the Return Code from a SAS Procedure

If there is an error in a SUBMIT block, your IMLPlus program will stop unless you handle the error. You can handle an error by using the OK= option on the SUBMIT statement. The OK= option enables you to specify the name of a SAS/IML matrix that contains a return code from the procedure. The matrix contains the value 0 if there was an error in the SUBMIT block; otherwise, the matrix contains a nonzero value.

This feature is described in Chapter 4, "Calling SAS Procedures."

You can also determine the cause of an error in many situations by examining certain SAS macro variables that are created by the procedures. This feature is described in Section 4.8.

5.3 Calling R Functions

You can call built-in or user-written functions in the R statistical programming language from within an IMLPlus program. You can load user-defined packages and call functions in those packages. You can exchange data between R and various SAS data formats. This feature is described in Chapter 11, "Calling Functions in the R Language."

5.4 IMLPlus Graphs

The most powerful computational feature in SAS/IML Studio is the ability to call SAS procedures from within an IMLPlus program, but SAS/IML Studio also provides rich functionality for creating and modifying statistical graphs.

The IMLPlus graphs have several characteristics that appeal to data analysts:

  1. The graphs are easy to create. You can create a graph with a single programming statement, or by using the SAS/IML Studio GUI through the Graph menu. SAS/IML Studio automatically handles the details of laying out the graph, including axes, labels, and margins. Graphs are introduced in Chapter 7, "Creating Statistical Graphs."

  2. The graphs are dynamically linked to each other. Observations that are selected in one graph are shown as highlighted in all other graphs that view the same data. This topic is introduced in Section 6.6.

  3. You can modify the default graph attributes, such as the placement of ticks and margins. This feature is described in Chapter 10, "Marker Shapes, Colors, and Other Attributes of Data."

  4. You can draw markers, lines, polygons, text, and other objects on a graph. This enables you to overlay the results of a statistical computation onto a scatter plot, histogram, or other graph. Collectively, the methods that draw on a plot are referred to as Draw methods because the names of the methods all begin with the "Draw" prefix. This feature is described in Chapter 9, "Drawing on Graphs."

5.5 Managing Data in Memory

The dynamically linked graphics in SAS/IML Studio are possible because SAS/IML Studio maintains an in-memory version of the data. You can programmatically query, manipulate, and modify these data. The data are managed by a class known as the DataObject class. You can use methods in the DataObject class to get or set properties of variables and observations. For details on the DataObject class, see Chapter 8, "Managing Data in IMLPlus."

5.6 Using Expressions When Reading or Writing Data

In the IML procedure, the names of data sets on the CREATE and USE statements have to be specified at the time that the statement is written. For example, the following statement is valid:

use Sashelp.Class;                        /* valid statement */

In the preceding statement, the data set name is resolved at the time that the statement is parsed. In PROC IML, it is not valid to use a character matrix to define a data set name at run time. The following statements are not valid:

DataName = "Sashelp.Class";
use DataName;                              /* invalid statement */

In the second set of statements, the USE statement tries to find the Work.DataName data set instead of recognizing that DataName is a character matrix that contains the string "Sashelp.Class." In the IML procedure, you can work around this by using the SAS Macro Language Facility.

In IMLPlus, the traditional syntax is supported, but you can also refer to the contents of a character matrix by placing parentheses around the matrix, as shown in the following statement:

use (DataName);                           /* valid IMLPlus statement */

Consequently, the names of data sets can be resolved at run time, rather than at parse time.

The statements in the following table are enhanced in IMLPlus to accept matrix expressions.

Table 5.1. Data Set Statements That Support Expressions in IMLPlus

CLOSE

CREATE

EDIT

SETIN

SETOUT

SORT

USE

 

Furthermore, in IMLPlus you can use a matrix expression (enclosed in parentheses) for the WHERE clause of any SAS/IML statement that has a WHERE clause. For example, the following statements are also valid in IMLPlus:

whereName = "Mpg_City";
DataName = "Sasuser.Vehicles";

use (DataName) where((whereName)>=33);    /* valid IMLPlus statement */
read all var {"Make" "Model"};
close (DataName);

5.7 IMLPlus Modules

IMLPlus modules have the same basic syntax as modules in PROC IML (see Section 3.4). In particular, IMLPlus modules are defined with the START and FINISH statements. However, IMLPlus modules differ from modules in PROC IML in several important ways:

  • Not only do IMLPlus modules accept SAS/IML matrices as arguments, but also they accept Java objects such as plots and data objects. This feature is described in Chapter 6, "Understanding IMLPlus Classes."

  • Although PROC IML modules must be defined prior to being called, you can define an IMLPlus module anywhere in your program. For example, you can put all of your modules at the end of your program. This is possible because the IMLPlus parser parses the entire program prior to executing the program.

  • In PROC IML you must load a module by using the LOAD statement prior to calling the module. This is not required in IMLPlus. IMLPlus modules are stored in directories on your Windows PC. If you add these directories to your module search path, then the modules are automatically loaded whenever they are called from a program.

  • You can dynamically define an alias for a module name. An alias is an alternative name for a module. It is similar to a function pointer in the C programming language.

These features are described in the following sections.

5.7.1 Storing and Loading IMLPlus Modules

A module is a group of statements that can be called from programs. In IMLPlus, the module can be defined anywhere in your program: at the top of the program, at the bottom, or anywhere in the middle.

If you write a module that you want to call from multiple programs, then you need to store the module. In SAS/IML Studio, modules are stored in a directory of the Windows PC that is running SAS/IML Studio. This is different from PROC IML, which stores modules in a catalog on a SAS Workspace Server. To store a module, you can use the STORE statement. But in what directory is the module stored? The module is stored in the default module storage directory (DMSD) on your Windows PC. To find the DMSD, select Tools5.7.1 Storing and Loading IMLPlus ModulesOptions from the SAS/IML Studio main menu. On the Options dialog box, select the Directories tab, as shown in Figure 5.1.

The Module Search Path

Figure 5.1. The Module Search Path

The Directories tab shows the directories that are automatically searched when IMLPlus tries to find a module. They are searched in the order shown in the Search Path list.

When you use the STORE statement, IMLPlus writes two files to the directory specified in the Default Storage Directory field. The root name for the files is the same as the name of the module. The source code that defines the module is written to a file with the extension .sxs. The executable form of the module is stored in a file with the extension .sxx.

What is potentially confusing is that IMLPlus stores the source code in the DMSD even if you are editing that source code in a different file! This could result in having two versions of the module source code.

For example, suppose you are writing a module called MyModule that is defined in the file C:MyProgram.sx. (The sx extension is used for SAS/IML Studio programs.) When you run the statement store module=MyModule, SAS/IML Studio creates a MyModule.sxs file and a MyModule.sxx file in your DMSD. If there is a run-time error in the module, SAS/IML Studio displays the version of the source code that is on the module search path, not the source code in C:MyProgram.sx. This might cause you to edit the copy in the DMSD instead of fixing the error in C:MyProgram.sx.

5.7.1.1 Conventions for Saving Modules

One way to avoid the previous problem is to carefully adhere to the following conventions when you write a stored module. Assume the name of your module is MyModule.

  1. Accept the current DMSD as shown in Figure 5.1, or set a new DMSD. The DMSD will contain the source and executable files for the module.

  2. Create a new program window in SAS/IML Studio (File5.7.1.1 Conventions for Saving ModulesNew5.7.1.1 Conventions for Saving Modules Workspace or CTRL+N). Type or paste in only the module definition and the STORE statement, as shown in the following statements:

    start MyModule( /* ... arguments ... */ );
       /* include all statements in the body of the module */
       x = 1;
       y = 2;
       /* and so forth */
    finish;
    store module=MyModule;
  3. Save the program to a file called MyModule.sxs in your current DMSD. Note that this file has the same name as the module.

  4. Run the program (Program5.7.1.1 Conventions for Saving ModulesRun or F5) to define and store the module.

You can now call the module from another program. By creating a file called MyModule.sxs in the DMSD, you prevent IMLPlus from creating a copy of the module source code. The file MyModule.sxs contains the only copy of the module source; if you need to update the module, edit that file.

5.7.1.2 Loading IMLPlus Modules

Unlike PROC IML, IMLPlus does not require that you use the LOAD statement prior to running a user-defined module. Provided that the module is on your module search path, the module does not need to be explicitly loaded. You can refer to the section "Summary of Module Storage Statements" in the online Help for other ways in which the LOAD, STORE, FREE, and REMOVE statements are different in IMLPlus than in PROC IML.

5.7.2 Local Variables in Modules

In PROC IML, a module that has no arguments implicitly uses variables in the global scope of the program. Inside the module, you can access variables from the global scope. Also, any new variables that you define in the module are accessible outside the module. For example, the following statements define a module in PROC IML that takes no arguments:

/* define PROC IML module with no arguments */
proc iml;
x=1;
start MyMod;                   /* module with no arguments          */
   y=x;                        /* x and y are both global variables */
finish;

run MyMod;                     /* assigns y to the value of x       */
print y;                       /* y is available outside the module */
A Variable That Is Global in Scope

Figure 5.2. A Variable That Is Global in Scope

Notice that the matrix x is defined in the main program. When the MyMod module is run, the module uses the matrix x to initialize the matrix y. Even though y is created within the module, the matrix y is also available outside the module.

In IMLPlus, you can use parentheses on the START statement to declare that you want the module to have local variables. The following statements define a module with local variables:

/* define IMLPlus module with no arguments */
x=1;                            /* x is defined in the main program */
start MyFunc();                 /* no arguments; local variables    */
   y=2;                         /* y is a local variable            */
   return ( y );                /* return the value of y            */
finish;

t = MyFunc();                   /* copies values into t             */

In this program, the MyFunc module takes no arguments, but the module contains local variables because parentheses are used on the START statement. Inside the module, the matrix x is not available unless you explicitly use a GLOBAL clause on the START statement. The local matrix y is defined in the module; you cannot access y from the main program.

5.7.3 Creating an Alias for a Module

An alias is the name of a module that can be set at run time. This means, for example, that you can pass the name of a module (that is, a character string) as an argument to another module, and the second module can call the first module.

As a simple example, this section describes how you might write a module to estimate the location parameter for univariate data. The sample mean is one estimator you can use, but a robust estimator such as the median is sometimes a better choice. You can define a module named Location that takes a string as an argument. The string determines whether to call a module that computes the mean or whether to call a module that computes the median.

The ALIAS statement enables you to do this. It enables you to specify the name of a module, and then call the module with that name. The following statements implement an IMLPlus function that uses the ALIAS statement:

/* write an IMLPlus module that estimates a location parameter */
start MyMean(x);
   return ( x[:,] );
finish;

/* The Median module already exists in IMLMLIB.
 * The syntax is Median(x).
 */

/* module that calls either the MyMean or the Median module */
start Location(StatName, x);
   alias *MyFunc(x) StatName;    /* MyFunc is an ALIAS              */
   y = MyFunc(x);                /* call function that is passed in */
   return ( y );                 /* value is returned               */
finish;

x = {1 2 1, 1 4 3, 1 5 3, 1 5 18};
mean = Location("MyMean", x);
median = Location("Median", x);
print mean, median;
The ALIAS Statement in IMLPlus

Figure 5.3. The ALIAS Statement in IMLPlus

The Location module uses the ALIAS statement to associate the name MyFunc to the module name that is contained in the StatName matrix. When the statement MyFunc(x) is executed, it can call the MyMean or Median module—or any other function module that takes one argument! Consequently, if you create a Trim10 module at some future date that computes the 10% trimmed mean, you can immediately make the following call without making any changes to the Location module:

trimMean = Location("Trim10", x);

Notice that an alternative way to write the Location module would be to use an IF-THEN/ELSE statement to look at the name of the StatName argument and conditionally call the appropriate module. However, that approach is not extensible: if you create a Trim10 module at some future date, you will also need to modify the definition of the Location module.

Notice that MyFunc is not a module, since it is not defined by using START and FINISH statements. Instead, it is an alias to a module. Some programming languages (such as C) have the concept of a function pointer. If you are familiar with function pointers, an alias is a similar concept.

IMLPlus needs to know whether an alias is to a function or a subroutine, and needs to know how many arguments are in the function. Some programming languages call this the prototype of a function. If you create an alias to a function (that is, to a module that returns a value), then prefix the name of the alias with an asterisk:

alias *MyFunc(x) StatName;       /* the module returns a value */

If, on the other hand, you create an alias to a subroutine (that is, to a module that does not return a value), then do not use an asterisk:

alias MySubroutine(x) StatName;  /* the module is a subroutine */

5.8 The IMLPlus Module Library

The IMLMLIB library of modules is distributed with SAS/IML software. This is a collection of documented modules that you can call when writing SAS/IML programs. You can call these modules from PROC IML and from SAS/IML Studio.

In addition, SAS/IML Studio 3.3 is distributed with more than 70 additional IMLPlus modules. These modules are only available from IMLPlus programs. The modules are contained in the Modules subdirectory of the SAS/IML Studio installation directory (for example, C:Program FilesSASSASIMLStudio3.3Modules), which is automatically part of the module search path. (See Figure 5.1.) The modules are documented in the SAS/IML Studio online Help, which you can display by selecting Help5.8 The IMLPlus Module LibraryHelp Topics from the main menu, and then by selecting the chapter titled "IMLPlus Module Reference." Most of the modules are documented in the sections titled "General Purpose," "Graphics," and "User Interface."

The next tables describe modules that are frequently used in statistical programs. Each module is documented fully in the online Help, and also contains an example that you can run to examine how the module works.

Table 5.2. General Purpose: Frequently Used IMLPlus Modules

IMLPlus Module

Description

CopyServerDataToDataObject

Copies variables from a SAS data set in a SAS libref into a data object (see Section 8.8.3)

GetPersonalFilesDirectory

Returns the Windows directory in which you should store data sets, modules, and programs related to SAS/IML Studio (see Section 12.10)

A color ramp is a sequence of colors that smoothly varies from one color to another. A color ramp is often used to visualize values of a continuous variable. Colors and coloring observations are described in Chapter 10, "Marker Shapes, Colors, and Other Attributes of Data." The following modules are useful for creating graphs that use color to visualize values of a variable.

Table 5.3. Graphics: Frequently Used IMLPlus Modules

IMLPlus Module

Description

BlendColors

Uses linear interpolation to create a color ramp from a vector of colors

ColorCodeObs

Sets the color of observation markers by mapping values of a single variable onto a color ramp

ColorCodeObsByGroups

Sets the color of observation markers by mapping values of one or more nominal variables to a set of colors

DrawInset

Displays an inset on a graph (see Section 9.2)

DrawLegend

Displays a legend on a graph (see Section 9.2)

DrawContinuousLegend

Displays a color ramp on a graph

DrawPolygonsByGroups

Displays a collection of polygons (such as a map) on a graph

IntToRGB

Converts a hexadecimal representation of colors into RGB triples (see Section 10.2.2)

RGBToInt

Converts RGB triples of colors into a hexadecimal representation (see Section 10.2.2)

The "User Interface" modules display dialog boxes of various types. SAS/IML Studio 3.3 has a variety of dialog boxes that you can use to solicit input from a person running a program. For example, you can display a simple dialog box such as a message box or a list box. A frequently used module is DoDialogGetListItems, which displays a dialog box with a list of items and prompts the user to select one or more items. These modules are described in the section "Querying for User Input" on page 126.

Table 5.4. User Interface: Frequently Used IMLPlus Modules

IMLPlus Module

Description

DoDialogGetDouble

Displays a dialog box that prompts the user for a number

DoDialogGetListItem

Displays a dialog box that prompts the user to select an item from a list

DoDialogGetListItems

Displays a dialog box that prompts the user to select one or more items from a list (see Section 16.5)

DoDialogGetString

Displays a dialog box that prompts the user for a character string

DoDialogModifyDouble

Displays a dialog box that prompts the user to accept or modify a default numeric value (see Section 16.5)

DoErrorMessageBoxOK

Displays an error dialog box that contains an OK button

DoMessageBoxOK

Displays a message dialog box that contains an OK button (see Section 16.5)

DoMessageBoxYesNo

Displays a message dialog box that contains a Yes button and a No button (see Section 16.5)

5.9 Features for Debugging Programs

Debugging a SAS/IML program in the SAS Enhanced Editor can be challenging. SAS/IML Studio has three features that make debugging programs easier. The first feature is that SAS/IML Studio has a program editor that colors keywords in the IMLPlus language. The second feature is that you can jump directly to the location of a programming error in the program window. The third feature is that you can use the PAUSE statement in conjunction with the Auxiliary Input window to debug your program.

5.9.1 Jumping to the Location of an Error

There are two kinds of errors that cause a program to report an error: the parse-time error and the run-time error. Common parse-time errors include mistyping a statement, forgetting a semicolon, or failing to close a set of parentheses. In all these cases, the syntax of the program is incorrect. In SAS/IML Studio, you can select Program5.9.1 Jumping to the Location of an ErrorCheck Syntax to check your program for parse-time errors.

On the other hand, a run-time error does not occur until the program is actually run. Common run-time errors include adding matrices that are different sizes, taking the logarithm of a negative value, and using the matrix index operator to specify indices that do not exist.

If you run a program and SAS/IML Studio reports a parse-time or run-time error, then the Error Log window appears. (The Error Log window appears automatically provided that the Auto activate property is selected in the Window tab of the Tools5.9.1 Jumping to the Location of an ErrorOptions dialog box. If the Auto activate property is not selected, you can view the Error Window by pressing the F8 key.) The error message in the Error Log window typically ends with a pair of numbers that indicate the position (line number and column number) of the error in the program window, as shown in Figure 5.4. To jump directly to the location of the error in the program window, do the following:

  1. Position the mouse cursor on the error message.

  2. Right-click the error message. A pop-up menu is displayed.

  3. Select the Go to Source menu item.

The program window becomes active and SAS/IML Studio positions the cursor at the location of the error. You can also go to an error location by pressing CTRL+G.

Jumping to an Error Location

Figure 5.4. Jumping to an Error Location

The following statements contain a run-time error:

/* define loop that contains a run-time error */
do x = 5 to 1 by -1;
   y = log(x);
   z = log(y);
end;

When you run the program, the following message appears in the Error Log:

»ERROR: (execution) Invalid argument to function.
»
» operation : LOG operands  : y
»
»y      1 row       1 col     (numeric)
»
»         0
»
ERROR: An error in the program occurred on the SAS server. (4, 11)

The first eight lines in the error message begin with the Jumping to an Error Location character. Lines beginning with the Jumping to an Error Location character are output by the SAS server (in this case, from SAS/IML software). The remaining lines are output by the IMLPlus language interpreter. The lines from the SAS server indicate the following:

  1. The error occurs in the argument to a function.

  2. The function being evaluated is the LOG function.

  3. The argument is the matrix y, which has one row, one column, is numeric, and has the value 0.

The portion of the message from the IMLPlus interpreter indicates that the error occurred on (or near) line 4 and column 11. If you right-click on the final line of the error message and choose Go to Source from the pop-up menu, then the cursor is placed on the indicated line and column. From this information, you should be able to determine that the program is unable to evaluate the LOG function at 0. (Recall that the logarithm function is not defined for nonpositive numbers.)

Parse-time errors are handled similarly.

5.9.2 Jumping to Errors in Modules

If an error occurs inside a module (or inside many nested modules), you can press CTRL+G to go to the statement in the main program that calls the outermost module in which the error occurred. You can then descend into the module by pressing SHIFT+F8. This means that SAS/IML Studio will display the source code for the module and position the cursor on the line in the module at which the error occurred. You can continue to follow errors into as many modules as necessary.

The following example is essentially the same as the previous one, except this time the run-time error occurs in a module:

/* define and call module that contains a run-time error */
start MyMod(k);
   do x = 5 to k by -1;
      y = log(x);
      z = log(y);
   end;
finish;

run MyMod(1);

When you run the program, the following message appears in the Error Log:

»ERROR: (execution) Invalid argument to function.
»
» operation : LOG operands : y
»
»y      1 row       1 col    (numeric)
»
»         0
»
ERROR: An error occurred while executing module "MyMod". (9, 1)
An error in the program occurred on the SAS server. (+4, 14)

The error message from the SAS server (the first eight lines) is the same as for the previous example. The message from the IMLPlus interpreter (the last two lines) is different. The first line says that the error occurred in the module MyMod when it was called from line 9 in the program. The second line indicates that, relative to the first line of the module, the error occurred on line 4, column 14. The START statement is considered the first line of a module. You can right-click on either line to go to the corresponding error location. Alternatively, you can press CTRL+G to go to the first error location, and SHIFT+F8 to descend into the module.

5.9.3 Using the Auxiliary Input Window as a Debugging Aid

The Auxiliary Input window is a pop-up window in which you can execute program statements when your program is paused. A program is implicitly paused when it encounters a run-time error. You can also explicitly pause a program by using the PAUSE statement (see the next section). A common use of the Auxiliary Input window is to print the value of variables in order to better understand why a program has experienced a run-time error.

In many situations, you can select View5.9.3 Using the Auxiliary Input Window as a Debugging AidAuxiliary Input (or press F7) to display the Auxiliary Input window, as shown in Figure 5.5. You can type any valid IMLPlus statement into the Input area. Press the Execute button to run only those statements. The statements are executed at the scope of the innermost module that contains the error.

Auxiliary Input Window

Figure 5.5. Auxiliary Input Window

For example, after the previous example stops with an error, you can press F7 to display the Auxiliary Input window, and then type the following statement in the Input area:

print k × y;

When you press Execute, the output from the PRINT statement is shown in the Auxiliary Input window. Notice that the variables k, x, and y are defined only in the module. This indicates that the Auxiliary Input window is executing statements within the scope of the MyMod module.

If the source code for the module that contains the error is not in the same program window as the statement that calls the module, then SAS/IML Studio opens a new workspace that contains the module source code. This often happens when the error occurs within a saved module.

5.9.4 Using the PAUSE Statement as a Debugging Aid

The error log can help you determine where an error occurred, but the PAUSE statement can help you determine why a program is not giving correct answers. The PAUSE statement can be used to debug a program that gives wrong answers, but that does not stop with an error. You can use the PAUSE statement in the main program and also inside modules.

For example, suppose you want to monitor the values of variables in a loop. The following statements use a PAUSE statement at the end of a loop to pause the program and display the Auxiliary Input window:

/* pause program at the end of each iteration */
do x = 5 to 1 by -1;
   y = log(x);
   z = log(y);
   pause "At the end of an iteration";
end;

The Auxiliary Input window displays the string specified on the PAUSE statement. You can type any valid IMLPlus statements into the Input area and click Execute to execute the statements. Figure 5.6 shows the Auxiliary Input window that appears at the end of the first iteration. A PRINT statement was typed into the Input area; the values of the x, y, and z variables at the end of the first iteration are shown in the Output area. When you click Resume, the program continues from the statement following the PAUSE statement.

If the text on the PAUSE statement begins with the string "NoDialog:", then the Auxiliary Input window is not displayed, but the program still pauses its execution. The remainder of the message is displayed in the SAS/IML Studio status bar (located in the lower left corner of the SAS/IML Studio application). This enables the person running the program to interact with the data before resuming the program, as described in Chapter 16, "Interactive Techniques."

The Auxiliary Input Window as a Debugging Aid

Figure 5.6. The Auxiliary Input Window as a Debugging Aid

5.10 Querying for User Input

SAS/IML Studio distributes modules that create and display several simple dialog boxes. All of these modules begin with the prefix "DoDialog" or "DoMessageBox." You can use these dialog boxes to query for user input or to display information to the user. These dialog boxes are modal, meaning that the program halts execution until the dialog box is dismissed. These modules are described in Chapter 16, "Interactive Techniques."

5.11 Differences between IMLPlus and the IML Procedure

This chapter primarily focuses on ways that the IMLPlus programming language extends the SAS/IML language. Most computational modules and programs that run in the IML procedure also run in IMLPlus without modification. However, there are a small number of SAS/IML statements and functions that are not supported in IMLPlus. The differences are described in the online Help in the chapter "The IMLPlus Language."

Of these differences, the most important PROC IML statement that is not available in IMLPlus is the EXECUTE subroutine.

Another major difference is that IMLPlus programs do not intrinsically support SAS System global statements. For example, the following statements are not supported in IMLPlus:

  • Global SAS statements such as LIBNAME, FILENAME, and TITLE.

  • The OPTIONS statement.

  • The ODS statement.

  • Macro language statements. This includes using %let to define macro variables and using %macro to define macro functions, in addition to making calls to macro functions. Use the SYMGET and SYMPUT functions in Base SAS software to create macro variables from SAS/IML matrices, and vice versa.

You can still use these statements provided that you use them in a SUBMIT block. You can also submit these global statements by using the @ symbol, as described in Chapter 3, "Programming Techniques for Data Analysis."

IMLPlus does not support the PROC IML low-level drawing routines such as GSTART, GOPEN, GPOLY, GPOINT, and GSHOW. Instead, IMLPlus provides high-level statistical graphs such as scatter plots, histograms, and box plots. IMLPlus also provides methods for drawing markers, lines, polygons, text, and other graphical objects on a plot. Section 9.10 provides a comparison between drawing in IMLPlus and drawing in PROC IML.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset