Hi Guys,
I’m in process of converting an excel report into sas proc iml code.
I have to achieve the below, can anyone give me a hand please?
Attached in the sample data set.
I think this will do what you want:
proc iml;
x = {1 . 3, 4 5 6, -5 4 1};
n = nrow(x);
y = x / x[+, ]; /* divide by zero warnings in log */
y[do(1,n#n,n+1)] = 1; /* set diagonal to 1 */
idx = loc(y=.); /* find any missing values and replace with zero */
if ncol(idx)>0 then y[idx] = 0;
print x, y;
quit;
I have set up the first column of x to have a sum of zero, this generates missing values in the first column of y which are then replaced with zero.
I think this will do what you want:
proc iml;
x = {1 . 3, 4 5 6, -5 4 1};
n = nrow(x);
y = x / x[+, ]; /* divide by zero warnings in log */
y[do(1,n#n,n+1)] = 1; /* set diagonal to 1 */
idx = loc(y=.); /* find any missing values and replace with zero */
if ncol(idx)>0 then y[idx] = 0;
print x, y;
quit;
I have set up the first column of x to have a sum of zero, this generates missing values in the first column of y which are then replaced with zero.
Hi Ian,
A quick question. I want to check a condition .i.e. if the value is not zero then set the diagonal to 1.
I tried a lot but couldn't find what needs to be done to the below. Any help will really be appreciated.
Cheers
y[do(1,n#n,n+1)] = 1; /* set diagonal to 1 */
I think the following is what you need:
y[do(1,n#n,n+1)] = vecdiag(y)^=.;
which sets the diagonal to 1 wherever it is non-missing after the division, otherwise it is set to zero.
Excellent. Great stuff.
Hi Ian,
Trust you well. Just wondering if you can help with the below:
Now instead of 1 on the diagonal, i want 1- a matrix element.
For example:
y[do(1,n#n,n+1)] = 1- AR; (where AR is a matrix, of same shape)
y[do(1,n#n,n+1)] = (1- AR);
Both doesn't work. I get a error - "Matrix do not conform to the operation"
Any idea?
The left hand side is referring only to the diagonal elements, while the right hand side contains n^2 elements this is the reason for the non-conforming error message. The solution is to extract only the diagonal element of AR using the vecdiag function.
y[do(1,n#n,n+1)] = 1 - vecdiag(AR);
Thanks a Ton Ian. You are a genius!
Cheers
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.