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-2026-white.png



April 27 – 30 | Gaylord Texan | Grapevine, Texas

Registration is open

Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!

Register now

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