dear all
I have a data of size (108*40), I have computed the mean of each row and store in last column of my matrix. Now I want to creat a new matrix whdse entries will be 'each entry of old matrix-mean of each row. That means if A[108,40] is my old one and mean= mean (of val1-val40), then new matrix, B[108*40] will be
for i from 1 to 108;
for j from 1 to 40
B[i,j]= A[i,j]-mean[i]
How can do that?
Thanks in advance
I think @PaigeMiller is headed in the right direction. However, his program replaces your current values. In order to get new values, you need to decide on what variable names to use. So if you have VAL1-VAL40, let's call the new variables DIFFER1-DIFFER40:
data want;
set have;
array vals {40} val1-val40;
array differs {40} differ1-differ40;
do k=1 to 40;
differs{k} = vals{k} - mean;
end;
drop k;
run;
Just to be clear, are you performing these operations in SAS/IML?
@jamsher79 wrote:
performing in SAS
This is very ambiguous. Both data steps and PROC IML are in SAS.
This has to be done in PROC IML? It's pretty simple in a data step, rather than using the somewhat more complicated structures of PROC IML.
Assuming x40 is the column of means, and x1-x39 are the data, then
data want;
set have;
array x x1-x39;
do i=1 to 39;
x(i)=x(i)-x40;
end;
drop i;
run;
If you MUST do it in IML (and I don't think you do), use Matrix functions and then subtract two matrices, rather than creating the loops.
I think @PaigeMiller is headed in the right direction. However, his program replaces your current values. In order to get new values, you need to decide on what variable names to use. So if you have VAL1-VAL40, let's call the new variables DIFFER1-DIFFER40:
data want;
set have;
array vals {40} val1-val40;
array differs {40} differ1-differ40;
do k=1 to 40;
differs{k} = vals{k} - mean;
end;
drop k;
run;
Hope you are looking for a Data Step Solution. Here is a 3 by 5 matrix but it can be adapted to any dimensions by changing the sizes of the arrays in one place and body of the program needs no change.
data have;
input X1 - X5;
datalines;
10 12 15 10 13
20 22 15 30 23
21 30 25 18 46
;
run;
/* you compute the Mean */
data _null_;
array k[3,5] _temporary_;
array m[3] _temporary_;
do i = 1 by 1 until(eof);
set have end = eof;
array v X1 - X5;
do j = 1 to dim2(k);
k[i,j] = v[j];
end;
end;
if eof then do;
do i = 1 to dim1(k);
do j = 1 to dim2(k);
m[i] + k[i,j];
end;
m[i] = m[i] / dim2(k);
end;
do i = 1 to dim1(k);
do j = 1 to dim2(k);
k[i,j] = k[i,j] - m[i];
end;
do j = 1 to dim2(k);
put k[i,j] = ;
end;
end;
end;
run;
/* you use the SAS function to get Mean */
data _null_;
array k[3,5] _temporary_;
array m[3] _temporary_;
do i = 1 by 1 until(eof);
set have end = eof;
array v X1 - X5;
mean = mean(of v[*]);
put mean =;
do j = 1 to dim2(k);
k[i,j] = v[j] - mean;
end;
end;
if eof then do;
do i = 1 to dim1(k);
do j = 1 to dim2(k);
put k[i,j] =;
end;
end;
end;
run;
Hi @jamsher79,
Computations like these (subtracting a location measure and possibly dividing by a scale measure -- known as standardizing) can also be performed by PROC STDIZE (if SAS/STAT is available). This procedure operates on variables (i.e. columns), not observations (rows), though. But with PROC TRANSPOSE you can transpose your "matrices" as needed.
Here's a small 3x2 example:
data a;
input val1 val2;
cards;
1 3
2 5
4 8
;
proc transpose data=a out=at;
var val:;
run;
proc stdize data=at out=s method=mean;
var col:;
run;
proc transpose data=s out=b(drop=_:) prefix=sval;
run;
proc print data=b noobs;
run;
sval1 sval2 -1.0 1.0 -1.5 1.5 -2.0 2.0
So, PROC STDIZE using the option METHOD=MEAN has computed the means (val1+val2)/2, subtracted them from the original values val1, val2 and would have divided the differences by 1, the scale measure for this METHOD, if that had an impact. I've named the resulting variables sval1 and sval2. The PROC TRANSPOSE steps would be unnecessary if you were happy to work with transposed matrices (40x108 in your case). Please note that nowhere in the code the dimensions of matrix A had to be specified.
Compare this to the "Data Step Solution".
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.