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

Hi, All,

 

Suppose I simulate a dataset via do loop and get a matrix with below code.

My question is: How could I get the sum of x, by  i and j values?
Exactly speaking, I want to this:

denote sum as  a coloumn vector with dimention is 12*1, with sum[1]=sum(x1:x3) given i=j=1; sum[2]=sum(x2:x3) given i=1 and j=2;

.....sum[10]=sum(x10:x12) given i=4 and j=1; sum[11]=sum(x11:x12) given i=4 and j=2; sum[12]=sum(x12) given i=4 and j=3;

 

How should I program via PROC IML to reach such aim? Much appreciated for your help to a fresh to IML procedure.


data test;
	do i=1 to 4;
		do j=1 to 3;
		call streaminit(i*j);
		x=rand("normal");
		output;
	end;
end;
run;

PROC IML;
USE test var {i j x};
read all var {i j x} into TRY;
quit;
1 ACCEPTED SOLUTION

Accepted Solutions
IanWakeling
Barite | Level 11

One possibility might be to construct a matrix of zeros and ones (b) that gets the necessary sums by matrix multiplication.

 

a = {1 1 1, 0 1 1, 0 0 1};
b = block(a,a,a,a);
s = b * TRY[ ,3];
print b [format=1.0] s;

Here the BLOCK function places 4 copies of the 3x3 matrix 'a' on the diagonal of a 12x12 matrix.

 

View solution in original post

9 REPLIES 9
IanWakeling
Barite | Level 11

One possibility might be to construct a matrix of zeros and ones (b) that gets the necessary sums by matrix multiplication.

 

a = {1 1 1, 0 1 1, 0 0 1};
b = block(a,a,a,a);
s = b * TRY[ ,3];
print b [format=1.0] s;

Here the BLOCK function places 4 copies of the 3x3 matrix 'a' on the diagonal of a 12x12 matrix.

 

Jack2012
Obsidian | Level 7
Dear Ian, Very much appreciated for your creative idea. Yes, you are correct, this does work. However, if for a TRY with higher number of rows, like ten thousand, then b would be very huge, not sure there is any better solution to this. Many thanks, Jack
Jack2012
Obsidian | Level 7

Dear Ian,

 

Just checked the function of BLOCK in SAS web and found for the higher order of TRY, this method is not workable. I think I should go back to consider to the DATA step.

http://support.sas.com/documentation/cdl/en/imlug/59656/HTML/default/viewer.htm#langref_sect32.htm

Many thanks still for your creative idea.

 

Jack

 

 

Ksharp
Super User

Your logic is not clear for me . 

Why not use Data Step ? since it is not about VECTOR operation .

 

data test;
	do i=1 to 4;
		do j=1 to 3;
		call streaminit(i*j);
		x=rand("normal");
		output;
	end;
end;
run;
PROC IML;
use test nobs nobs;
read all var {i j x} into TRY;
close;

start=1:nobs;
end=start+repeat({2 1 0},1,int(nobs/3));

sum=j(nobs,1,.);
do i=1 to nobs;
 sum[i]=sum(try[start[i]:end[i],3]);
end;

print try sum;
quit;
Jack2012
Obsidian | Level 7

Dear KSharp,

I am really appreciated for your reply at very late night for you. Sorry for unclear logic of my question, but really I have to day, you really produced the right result I am hunting for.

 

And I fully agree with you maybe should use data step, as I am not working on the vector but block.

 

Many thanks.

 

Jack

Jack2012
Obsidian | Level 7

It seems I can't set two solutions, but I have to admit I prefer yours as it is easy to expand for simulation. Thanks.

Ksharp
Super User
Never mind. I really don't care about it.
IanWakeling
Barite | Level 11

Hi Jack,

 

I did not realise that you wanted to scale it to thousands of observations, so the 15 matrix limit on the BLOCK function is clearly a problem, and anyway you would not want to create and multiply zero/one matrices that large.   It is possible to vectorize the problem within IML by realising that what you want is not far away from the cumulative sum of the data vector in reverse.

n = 12;
m = 3;
c = cusum(TRY[n:1,3])[n:1];
s = c - (c[do(m+1, n-m+1, m)]//0) @ j(m, 1);
print try c s;

 

Where n is the total number of obsertations and m the sub-group size. 

 

Ian.

Jack2012
Obsidian | Level 7

Dear Ian,

 

Millionn thanks to your further code, yes, I think your logic is quite the same as Keshan's. Realy thank you both.

 

Jack.

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!

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.

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