Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

🔒 This topic is **solved** and **locked**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 04-17-2013 05:35 PM
(2316 views)

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

ivs

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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?

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

"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).

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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 ;

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

I'm glad you solved your problem.

Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.

**If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website. **

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.