Calcite | Level 5

## how to determine variable name and row name for a single value within a matrix?

hi i have an IML question. i am trying to determine coordinates for a maximum value within a matrix. for example:

data one;

input name \$ a b c;

datalines;

a 10 20 30

b 10 100 30

c 30 20 10

;

run;

proc iml;

use one;

read all into X [rowname=name colname=VarName];

n=max(X);

print n;

quit;

output just lists "N 100." how to output that n is variable "b" in row name "b"? Many thanks in advance for your help!

ivs

1 ACCEPTED SOLUTION

Accepted Solutions
SAS Super FREQ

## Re: how to determine variable name and row name for a single value within a matrix?

Your logic looks OK, but the code is inefficient. There is no need to loop over all rows and columns of your matrix. You can use arithmetic to find the row and column directly, which is what I show in the blog post that I linked to earlier.

start ind2sub( p, ind );
idx = colvec(ind);
n = nrow(idx);
col = 1 + mod(idx-1, p);
row = 1 + (idx-col) / p;
return ( row || col );
finish;

a=X[<:>]; *finding position of max value within the entire matrix;
rowcol = ind2sub(ncol(X), a); *call function get (row,col) directly without looping;
RowM=rowcol[1];
ColM=rowcol[2];

RowN=name[RowM]; *lookup row name for max value;
ColN=VarName[ColM]; *lookup col name for max value;
print a RowN ColN ;

9 REPLIES 9
SAS Super FREQ

## Re: how to determine variable name and row name for a single value within a matrix?

Use the <:> opertor to find the index of the largest element. See SAS/IML(R) 9.3 User's Guide

Because the elements of a matrix are enumerated in row-major order, you can figure out the row and column by knowing the dimensions of the matrix and the index of the maximum.  You can do this by hand or you can use the NDX2SUB function in SAS/IML 12.1.  If you don't have SAS/IML 12.1, you can easily write down an equivalent function, as shown in this article: Converting matrix subscripts to indices - The DO Loop

/* 12.1 solution */

maxIdx = X[<:>];

rowcol = ndx2sub(dimension(X), maxIdx);

print maxIdx rowcol;

maxIdx     rowcol

5                2  2

Calcite | Level 5

## Re: how to determine variable name and row name for a single value within a matrix?

Thanks Rick. I do not have SAS/IML 12.1 - going to try the Do Loop approach.

ivs

Calcite | Level 5

## Re: how to determine variable name and row name for a single value within a matrix?

hi Rick, there is no DO LOOP solution to my question in the link you provided - just discussion on converting subscripts to indices and the other way around via declaring a module. in fact there is no singe DO LOOP in the entire article. I am looking for something simple without complex module declarations.

thanks for pointing out the X[<:>] option. now that i know the element index and can calc ncol and nrow what's a simple way to add corresponding row number and column name to the element?

SAS Super FREQ

## Re: how to determine variable name and row name for a single value within a matrix?

"The DO Loop" is the name of the blog.

If you know the row and column of the maximum, then name[row] is the name of row ("b") and VarName[col] is the name of the variable (also "b" for this example).

Calcite | Level 5

## Re: how to determine variable name and row name for a single value within a matrix?

thank you for your quick response. i am still unable to determine the row and column for the maximum base on its index value. please help!

Calcite | Level 5

## Re: how to determine variable name and row name for a single value within a matrix?

hey Rick, i think i solved it. Let me know if you see any errors in my logic. Many thanks in advance for your opinion.

ivs

data one;

input name \$ a b c d;

datalines;

a 10 10 30 10

b 10 10 300 10

c 30 10 10 10

;

run;

proc iml;

use one; *reading data into matrix;

read all into X [rowname=name colname=VarName];

a=X[<:>]; *finding position of max value within the entire matrix;

col=ncol(X); *number of columns in the matrix;

row=nrow(X); *number of rows in the matrix;

/*calc row number 'RowM' for the max value based on the max value position*/

do i=1 to row;

if a<=col then RowM=1;

else do j=1 to col;

if a=j+col*(i-1) then RowM=i;

end;

end;

ColM=a-col*(RowM-1); *calc column 'ColM' number for the max value;

RowN=name[RowM]; *lookup row name for max value;

ColN=VarName[ColM]; *lookup col name for max value;

print X RowN ColN ;

run;

quit;

result:

X             a         b         c         d    ROWN     COLN

a               10        10        30        10 b        c

b               10        10       300        10

c               30        10        10        10

SAS Super FREQ

## Re: how to determine variable name and row name for a single value within a matrix?

Your logic looks OK, but the code is inefficient. There is no need to loop over all rows and columns of your matrix. You can use arithmetic to find the row and column directly, which is what I show in the blog post that I linked to earlier.

start ind2sub( p, ind );
idx = colvec(ind);
n = nrow(idx);
col = 1 + mod(idx-1, p);
row = 1 + (idx-col) / p;
return ( row || col );
finish;

a=X[<:>]; *finding position of max value within the entire matrix;
rowcol = ind2sub(ncol(X), a); *call function get (row,col) directly without looping;
RowM=rowcol[1];
ColM=rowcol[2];

RowN=name[RowM]; *lookup row name for max value;
ColN=VarName[ColM]; *lookup col name for max value;
print a RowN ColN ;

Calcite | Level 5

## Re: how to determine variable name and row name for a single value within a matrix?

Thank you Rick! Now i see how the function works. sorry i am a bit slow.

SAS Super FREQ