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

I have a problem I am trying to solve using a do loop with proc iml.  What I am trying to do is take each data point from column "y" one at a time, and multiply it by the vector x, and create a column "z" which is the sum of each iteration of the loop.

 

 

data example;
input x y;
datalines;
1 2
3 6
5 10
7 14
9 18
;

proc iml;
use work.example;
read all var{x} into x;
do i=1 to 5;
read point i var{y} into y;
z=x*y;
end;
print z;

For example if I run this it will give me the z output as:

 

18

54

90

126

162

This is just taking the last iteration of the loop with y=18 and multiplying by the "x" column.  What I am trying to do is get results like:

z

2+6+10+14+18=50 (first iteration)

.

.

.

.

18+54+90+126+162=450 (last iteration)

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User
How about this one .



data example;
input x y;
datalines;
1 2
3 6
5 10
7 14
9 18
;

proc iml;
use work.example;
read all var{x y} ;
close;
z=(y*x`)[,+];

print z;
quit;


View solution in original post

5 REPLIES 5
thomp7050
Pyrite | Level 9
data example;
input x y;
datalines;
1 2
3 6
5 10
7 14
9 18
;

PROC SQL;
CREATE TABLE MYJOIN AS
SELECT EXAMPLE1.X, EXAMPLE2.Y, EXAMPLE1.X * EXAMPLE2.Y AS MULT
FROM EXAMPLE AS EXAMPLE1, EXAMPLE AS EXAMPLE2;
QUIT;

PROC SQL;
CREATE TABLE SUMS AS
SELECT MYJOIN.X, SUM(MULT) AS TOTAL FROM MYJOIN GROUP BY MYJOIN.X;
QUIT;
Ksharp
Super User
How about this one .



data example;
input x y;
datalines;
1 2
3 6
5 10
7 14
9 18
;

proc iml;
use work.example;
read all var{x y} ;
close;
z=(y*x`)[,+];

print z;
quit;


dsriggs
Fluorite | Level 6

Wow that is some witchcraft! I can't believe how simple that is.  Could you explain the syntax?  Particularly what the backtick symbol does in this situation, and how [,+] works?

Ksharp
Super User

For example:

 

x   y

1   4

2   5

3   6

 

 

` means transpose operator

 

y*x` =

4                              4 8 12

5    *   1 2 3    =        5 10 15

6                              6 12 18

 

[,+]  mean sum each row   

 

4 8 12   = 24

.......

.......

Rick_SAS
SAS Super FREQ

I like KSharp's solution, which doesn't require a loop.  If you are required to use a loop (maybe for a homework assignment or because this is a simplification of a more complicated computation), the following program shows how to iterate over the elements of x to form each element of z:

 

proc iml;
use work.example;
read all var {x y};      /* read all data */
close;
z = j(nrow(x),1,.);      /* allocate result vector */
do i=1 to nrow(x);
   z[i] = sum(x[i] * y); 
end;
print z;

KSarp's solution uses a concept called "vectorizing" a program. For more about how to vectorize a SAS/IML program, see the article "How to vectorize computations in a matrix language."