Working with Matrices

Subscripts

Subscripts are special postfix operators placed in square brackets ([ ]) after a matrix operand. Subscript operations have the general form operand[row,column] where

operand

is usually a matrix name, but it can also be an expression or literal.

row

refers to a scalar or vector expression that selects one or more rows from the operand.

column

refers to a scalar or vector expression that selects one or more columns from the operand.

You can use subscripts to do any of the following:

  • refer to a single element of a matrix

  • refer to an entire row or column of a matrix

  • refer to any submatrix contained within a matrix

  • perform a reduction across rows or columns of a matrix. A reduction is a statistical operation (often a sum or mean) applied to the rows or to the columns of a matrix.

In expressions, subscripts have the same (high) precedence as the transpose postfix operator (`). When both row and column subscripts are used, they are separated by a comma. If a matrix has row or column names associated with it from a MATTRIB or READ statement, then the corresponding row or column subscript can also be a character matrix whose elements match the names of the rows or columns to be selected.

Selecting a Single Element

You can select a single element of a matrix in several ways. You can use two subscripts (row, column) to refer to its location, or you can use one subscript to index the elements in row-major order.

For example, for the coffee example used previously in this chapter, there are several ways to find the element that corresponds to the number of cups that Samuel drank on Monday.

First, you can refer to the element by row and column location. In this case, you want the fourth row and first column. The following statements extract the datum and place it in the matrix c41:

coffee={4 2 2 3 2, 3 3 1 2 1, 2 1 0 2 1, 5 4 4 3 4};
names={Jenny, Linda, Jim, Samuel};
print coffee[rowname=names];
c41 = coffee[4,1];
print c41;

Figure 17: Datum Extracted from a Matrix

coffee
JENNY42232
LINDA33121
JIM21021
SAMUEL54434

c41
5


You can also use row and column names, which can be assigned with an MATTRIB statement as follows:

mattrib coffee rowname=names
   colname={'MON' 'TUE' 'WED' 'THU' 'FRI'};
cSamMon = coffee['SAMUEL','MON'];
print cSamMon;

Figure 18: Datum Extracted from a Matrix with Assigned Attributes

cSamMon
5


You can also look for the element by enumerating the elements of the matrix in row-major order. In this case, you refer to this element as the sixteenth element of coffee:

c16 = coffee[16];
print c16;

Figure 19: Datum Extracted from a Matrix by Specifying the Element Number

c16
5


Selecting a Row or Column

To refer to an entire row of a matrix, specify the subscript for the row but omit the subscript for the column. For example, to refer to the row of the coffee matrix that corresponds to Jim, you can specify the submatrix that consists of the third row and all columns. The following statements extract and print this submatrix:

jim = coffee[3,];
print jim;

Alternately, you can use the row names assigned by the MATTRIB statement. Both results are shown in Figure 20.

jim2 = coffee['JIM',];
print jim2;

Figure 20: Row Extracted from a Matrix

jim
21021

jim2
21021


If you want to extract the data for Friday, you can specify the subscript for the fifth column. You omit the row subscript to indicate that the operation applies to all rows. The following statements extract and print this submatrix:

friday = coffee[,5];
print friday;

Figure 21: Column Extracted from a Matrix

friday
2
1
1
4


Alternatively, you could also index by the column name as follows:

friday = coffee[,'FRI'];

Submatrices

You refer to a submatrix by specifying the rows and columns that determine the submatrix. For example, to create the submatrix of coffee that consists of the first and third rows and the second, third, and fifth columns, use the following statements:

submat1 = coffee[{1 3}, {2 3 5}];
print submat1;

Figure 22: Submatrix Extracted from a Matrix

submat1
222
101


The first vector, {1 3}, selects the rows and the second vector, {2 3 5}, selects the columns. Alternately, you can create the vectors of indices and use them to extract the submatrix, as shown in following statements:

rows = {1 3};
cols = {2 3 5};
submat1 = coffee[rows,cols];

You can also use the row and column names:

rows = {'JENNY' 'JIM'};
cols = {'TUE' 'WED' 'FRI'};
submat1 = coffee[rows, cols];

You can use index vectors generated by the index creation operator (:) in subscripts to refer to successive rows or columns. For example, the following statements extract the first three rows and last three columns of coffee:

submat2 = coffee[1:3, 3:5];
print submat2;

Figure 23: Submatrix of Contiguous Rows and Columns

submat2
232
121
021


Selecting Multiple Elements

All SAS/IML matrices are stored in row-major order. This means that you can index multiple elements of a matrix by listing the position of the elements in an n times p matrix. The elements in the first row have positions 1 through p, the elements in the second row have positions p plus 1 through 2 p, and the elements in the last row have positions left-parenthesis n minus 1 right-parenthesis p plus 1 through n p.

For example, in the coffee data discussed previously, you might be interested in finding occurrences for which some person (on some day) drank more than two cups of coffee. The LOC function is useful for creating an index vector for a matrix that satisfies some condition. The following statement uses the LOC function to find the data that satisfy the desired criterion:

h = loc(coffee > 2);
print h;

Figure 24: Indices That Correspond to a Criterion

h
 COL1COL2COL3COL4COL5COL6COL7COL8COL9
ROW114671617181920


The row vector h contains indices of the coffee matrix that satisfy the criterion. If you want to find the number of cups of coffee consumed on these occasions, you need to subscript the coffee matrix with the indices, as shown in the following statements:

cups = coffee[h];
print cups;

Figure 25: Values That Correspond to a Criterion

cups
4
3
3
3
5
4
4
3
4


Notice that SAS/IML software returns a column vector when a matrix is subscripted by a single array of indices. This might surprise you, but clearly the cups matrix cannot be the same shape as the coffee matrix since it contains a different number of elements. Therefore, the only reasonable alternative is to return either a row vector or a column vector. Either would be a valid choice; SAS/IML software returns a column vector.

Even if the original matrix is a row vector, the subscripted matrix will be a column vector, as the following example shows:

v = {-1 2 5 -2 7};  /* v is a row vector */
v2 = v[{1 3 5}];    /* v2 is a column vector */
print v2;

Figure 26: Column Vector of Extracted Values

v2
-1
5
7


If you want to index into a row vector and you want the resulting variable also to be a row vector, then use the following technique:

v3 = v[ ,{1 3 5}];  /* Select columns. Note the comma. */
print v3;

Figure 27: Row Vector of Extracted Values

v3
-157


Subscripted Assignment

You can assign values into a matrix by using subscripts to refer to the element or submatrix. In this type of assignment, the subscripts appear on the left side of the equal sign. For example, to assign the value 4 in the first row, second column of coffee, use subscripts to refer to the appropriate element in an assignment statement, as shown in the following statements and in Figure 27:

coffee[1,2] = 4;
print coffee;

To change the values in the last column of coffee to zeros, use the following statements:

coffee[,5] = {0,0,0,0};   /* alternatively: coffee[,5] = 0; */
print coffee;

Figure 28: Matrices after Assigning Values to Elements

coffee
44232
33121
21021
54434

coffee
44230
33120
21020
54430


In the next example, you locate the negative elements of a matrix and set these elements to zero. (This can be useful in situations where negative elements might indicate errors.) The LOC function is useful for creating an index vector for a matrix that satisfies some criterion. The following statements use the LOC function to find and replace the negative elements of the matrix T:

t = {3  2 -1,
     6 -4  3,
     2  2  2 };
i = loc(t<0);
print i;
t[i] = 0;
print t;

Figure 29: Results of Finding and Replacing Negative Values

i
35

t
320
603
222


Subscripts can also contain expressions. For example, the previous example could have been written as follows:

t[loc(t<0)] = 0;

If you use a noninteger value as a subscript, only the integer portion is used. Using a subscript value less than one or greater than the dimension of the matrix results in an error.

Last updated: July 20, 2026