BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
jamsher79
Calcite | Level 5

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

                                       

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

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;

View solution in original post

7 REPLIES 7
PeterClemmensen
Tourmaline | Level 20

Just to be clear, are you performing these operations in SAS/IML?

jamsher79
Calcite | Level 5
performing in SAS

PaigeMiller
Diamond | Level 26

@jamsher79 wrote:
performing in SAS


This is very ambiguous. Both data steps and PROC IML are in SAS.

--
Paige Miller
PaigeMiller
Diamond | Level 26

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.

--
Paige Miller
Astounding
PROC Star

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;

KachiM
Rhodochrosite | Level 12

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;
FreelanceReinh
Jade | Level 19

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

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 7 replies
  • 744 views
  • 1 like
  • 6 in conversation