BookmarkSubscribeRSS Feed
Macro
Obsidian | Level 7

Hi,

 

I have a dataset with two columns like the following:

 

data temp;

input item count;

datalines;

a1   n1

a2   n2

a3   n3

...

ak   nk

;

run;

 

Basically, {n1, n2, ...,n k} are the counts of {a1,... ak}. I would like to compute the number b= (n1*n2 + n1*n3+ ... +n1*nk) + (n2*n3 + n2*n4+...n2*nk) + ...+

(n_(k-1) *nk). Is there any efficient way to do it?

 

Thanks.

 

   

6 REPLIES 6
Macro
Obsidian | Level 7

It appears this non-IML way is incorrect.

Rick_SAS
SAS Super FREQ

The straightforward way is efficient and simple to understand:

data temp;
input item $ count;
datalines;
a1   2
a2   4
a3   3
a5   2
a5   1
a6   5
;

proc iml;
use temp;
read all var "count" into n;
close;
k = nrow(n);

/* simplest way */
sum = 0;
do i = 1 to k-1;
   sum = sum + n[i]*sum(n[(i+1):k]);
end;
print sum;

If by "efficient" you mean "vectorized," you can get rid of the DO loop by noting that the SUM() function inside the loop is computing the cumulative sums of the vector n in reverse order.  Thus you could use the CUSUM function to compute the cumulative sums and then perform an inner product with n to get the sum:

 

/* use cumulative sums of the reverse of n */
m = n[ k:1 ];   /* reverse n */
cs = cusum(m);  /* cumulative sums */
c = cs[k:1];    /* reverse the cumulative sums */
*print c;       /* if you need to see the cumulative sums */
/* inner product of n and (reverse) cumulative sums */
sum = n[1:(k-1)]` * c[2:k];   
print sum;
Macro
Obsidian | Level 7

Hi Rick,

 

Very nice solution. Actually my goal is to use this sum inside of my code to do some additional computation, instead of just printing it. How do I send this sum to a macro variable to save it and do further computation from inside proc iml and then close proc iml to proceed outside of proc iml? Can I use %let statement inside proc iml or it has other interface to send this sum out to a macro variable? Thanks.

Rick_SAS
SAS Super FREQ

CALL SYMPUT("MyMacro", char(sum));

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

Register now!

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 6 replies
  • 1379 views
  • 0 likes
  • 4 in conversation