BookmarkSubscribeRSS Feed
dustychair
Pyrite | Level 9

Hi all,

 How can I extract lower triangular of a matrix? VECH or SYMSQR functions exports elements in column order but I want exactly the triangular shape.

Thanks

5 REPLIES 5
PeterClemmensen
Tourmaline | Level 20

Do something like this

 

proc iml;

A={1 2 3 4 7,
   4 5 6 5 3,
   7 8 9 2 5,
   2 5 8 6 1,
   7 9 4 2 9};

UpperIdx = loc(row(A) < col(A));

LowerTr=A;
LowerTr[UpperIdx]=0;

print LowerTr;

quit;
dustychair
Pyrite | Level 9

Hi Draycut,

It worked. When I modify it to my matrix I don't get my matrix's column and rows.What am I missing here?

 

proc iml;
use my_matrix;

read all var _NUM_ into my_matrix;
close;
y=my_matrix;
UpperIdx = loc(row(my_matrix) < col(my_matrix));

LowerTr=my_matrix;
LowerTr[UpperIdx]=0;

print LowerTr;

quit;

PeterClemmensen
Tourmaline | Level 20

Hi @dustychair. I'm glad to hear it worked. 

 

I don't understand what you mean by "I don't get my matrix's column and rows". Can you be more specific?

dustychair
Pyrite | Level 9

Actually, I'm working on the code you wrote. I have candidates id's in the columns and rows. I want to have candidates id's in the triangular matrix. there is output of results in the attachment.

 

proc iml;
use tr; read all var _ALL_; close tr;

Cand=unique(Cand_1//Cand_2);
call sort(Cand);

X=j(ncol(Cand), ncol(Cand), .);
do i=1 to nrow(rt);
X[loc(Cand=Cand_1[i]),loc(Cand=Cand_2[i])]=rt[i];
end;

/* replace missing values with 0 */
missIdx = loc(X=.); /* locations of missing values */
nonmissIdx = loc(X^= ); /* locations of nonmissing values */
X[missIdx] = 0.5; /* replace missing with 0 */
Z = X; /* make a copy */
Z[nonmissIdx] = .; /* replace orig probs with missing */
X = X + Z`; /* use missing values for lower triangular probabilities */

print X[colName=((Cand)) rowName=((Cand))];

create matrix from X [colname=Cand rowname=Cand];
append from X[rowname=Cand];
close;
quit;

 

proc iml;
use matrix;

read all var _NUM_ into matrix;
close;
y=matrix;
UpperIdx = loc(row(matrix) < col(matrix));

LowerTr=matrix;
LowerTr[UpperIdx]=0;

print LowerTr;

quit;

Rick_SAS
SAS Super FREQ

On the READ statement, use the ROWNAME= option to also read the IDs:

 

proc iml;
use matrix;
read all var _NUM_ into matrix[rowname=Cand];
close;

UpperIdx = loc(row(matrix) < col(matrix));
LowerTr=matrix;
LowerTr[UpperIdx]=0;
print LowerTr[rowname=Cand colname=Cand];

sas-innovate-white.png

Missed SAS Innovate in Orlando?

Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.

 

Register now

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 5 replies
  • 1980 views
  • 2 likes
  • 3 in conversation