DATA Step, Macro, Functions and more

new matrix

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 5
Accepted Solution

new matrix

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

                                       


Accepted Solutions
Solution
2 weeks ago
Super User
Posts: 6,928

Re: new matrix

Posted in reply to jamsher79

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


All Replies
PROC Star
Posts: 1,400

Re: new matrix

Posted in reply to jamsher79

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

Occasional Contributor
Posts: 5

Re: new matrix

performing in SAS

Respected Advisor
Posts: 3,261

Re: new matrix

Posted in reply to jamsher79

@jamsher79 wrote:
performing in SAS


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

--
Paige Miller
Respected Advisor
Posts: 3,261

Re: new matrix

Posted in reply to jamsher79

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
Solution
2 weeks ago
Super User
Posts: 6,928

Re: new matrix

Posted in reply to jamsher79

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;

Super Contributor
Posts: 331

Re: new matrix

Posted in reply to jamsher79

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;
Trusted Advisor
Posts: 1,323

Re: new matrix

Posted in reply to jamsher79

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

☑ This topic is solved.

Need further help from the community? Please ask a new question.

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