The Do Loop

Lists: Nonmatrix data structures in SAS/IML

Lists are collections of objects. SAS/IML 14.2 supports lists as a way to store matrices, data tables, and other lists in a single object that you can pass to functions. SAS/IML lists automatically grow if you add new items to them and shrink if you remove items. You can also modify existing items. You can use indices to refer to items of a list, or you can assign names to the items to create a named list.

Create a list

You can create a list by using the ListCreate function. If you know how many items the list will contain, you can specify the list length when you create the list. You can then use the ListSetItem subroutine to assign a value to each item:

proc iml;
L = ListCreate(2); /* L is two-item list */
call ListSetItem(L, 1, 1:3); /* 1st item is 1×3 vector */
call ListSetItem(L, 2, {4 3, 2 1}); /* 2nd item is 2×2 matrix */

The arguments for the ListSetItem subroutine are list, index, and value, which is the same order that you use when you assign a value to a matrix element, such as A[2] = 5.

If you do not know how many items the list will contain, or if you later want to add additional items, you can use the ListAddItem subroutine to append new items to an existing list. The list will automatically grow to accommodate the new item:

X = {3 1 4, 2 5 3}; /* create a 2×3 matrix */
call ListAddItem(L, X); /* add 3rd item; list grows */

Notice that the syntax for the ListAddItem subroutine only requires the list and the value because the new item is always added to the end of the list. At this point, the list contains three items, as shown below:

SAS Certifications Tutorials and Materials, SAS Certifications Guide, SAS Certifications

Insert, modify, and delete list items

A convenient feature of SAS/IML lists is that they automatically resize. You can insert new items into any position in the list. You can also replace an existing item or delete an item. The following statements demonstrate modifying an existing list.

call ListInsertItem(L, 2, -1:1); /* insert new item before item 2; list grows */
call ListSetItem(L, 1, {A B, C D}); /* replace 1st item with 2×2 character matrix */
call ListDeleteItem(L, 3); /* delete 3rd item; list shrinks */

The arguments for the ListInsertItem subroutine are again list, index, and value. Inserting an item at position k means that the new item becomes the tth item and existing higher-indexed items are renumbered. (Conceptually, imagine some items “move to the right” to “make room” for the new item.) If you delete the item at position k, existing higher-indexed items are also renumbered. (Conceptually, items “move to the left.”) After the previous sequence of operations, the list contains the following items:

You can insert, modify, and delete items in a SAS/IML list

SAS Certifications Tutorials and Materials, SAS Certifications Guide, SAS Certifications

Create named lists

In the previous section, the list acted like a dynamic array: it stored items that you could access by using indices such as 1, 2, and 3. For some applications, it makes more sense to name the list items and refer to the items by their names rather than their positions. This is similar to “structs” in some languages, where you can refer to members of a struct by name.

For example, suppose a teacher wants to store information about students in her classes. For each student, she might want to store the student’s name, class, and test scores. The following statements create a SAS/IML list that has three items named “Name”, “Class”, and “Scores”. The items are then assigned values:

Student = ListCreate({“Name” “Class” “Scores”}); /* create named list with 3 items */
call ListSetItem(Student, “Name”, “Ron”); /* set “name” value for student */
call ListSetItem(Student, “Class”, “Statistics”); /* set “class” value for student */
Tests = {100 97 94 100 100}; /* test scores */
call ListSetItem(Student, “Scores”, Tests); /* set “scores” value for student */

Although you can still use positional indices to access list items (“Ron” is the first item, “Statistics” is the second item, …), you can also use the name of items. For example, to extract the test scores into a SAS/IML matrix or vector, you can use the ListGetItem function, as follows:

s = ListGetItem(Student, “Scores”); /* get test scores from list */

Lists are for storing items, not for computing. You cannot add, subtract, or multiply lists. However, the example shows that you can extract an item into a matrix and subsequently perform algebraic operations on the matrix.

Lists of lists

Lists can contain sublists. In this way you can represent nested or hierarchical data. For example, the teacher might want to store information about several students. If information about each student is stored in a list, then she can use a list of lists to store information about multiple students.

The following statements create a list called All. The first student (“Ron”) is added to the list, which means that the item is a copy of the Student list. Then information about a second student (“Karl”) is stored in the Student list and copied into the All list as a second item. This process could continue until all students are stored in the list.

All = ListCreate(); /* empty list */
call ListAddItem(All, Student); /* add “Ron” to list */

call ListSetItem(Student, “Name”, “Karl”);
call ListSetItem(Student, “Class”, “Calculus”);
call ListSetItem(Student, “Scores”, {90 92 84 70 80});
call ListAddItem(All, Student); /* add “Karl” to list */

At this point, the All list contains two items. Each item is a list that contains three items.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s