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

Hello,
I would like to reshape the matrix A :
   1   2   3
   4   5   6
   7   8   9
 10 11 12
 13 14 15
 16 17 18
 19 20 21
 22 23 24

which is (8*3) into the following matrix (4*6):
  1   2   3 13 14 15
  4   5   6 16 17 18
  7   8   9 19 20 21
10 11 12 22 23 24

In the following code, test2 delivers this for this simplified example, but it does not suit when the actual matrix is for example (9000*3) and has to be reshaped in (450*60), i.e each of the 20 blocks of (450*3) moves on the right, one after another. So I would prefer a code more general like test1, but the shape function - in this form at least - does not deliver the result I want.

 

proc IML;
	A = {1 2 3, 4 5 6, 7 8 9, 10 11 12, 13 14 15, 16 17 18, 19 20 21, 22 23 24};
	test1 = shape(A, 4, 6);
	test2 = A[1:4,] || A[5:8,];
quit;

Thank you for your help,

1 ACCEPTED SOLUTION

Accepted Solutions
IanWakeling
Barite | Level 11

I think this might do what you want, where all you need to do is pre-specify the number of blocks required.

 

proc iml;

x = shape(1:36,12,3);
print x;

nblocks = 3;
cidx = shape(1:ncol(x)#nblocks, ncol(x), nblocks);
y = shapecol(x, nrow(x)/nblocks)[ ,t(cidx)];
print y;
quit;

View solution in original post

6 REPLIES 6
Rick_SAS
SAS Super FREQ

If the original matrix is N x 3, it is not clear to me how you are forming the final matrix in terms of N. For example, in the 9000 x 3 example, what are the rules for getting the 450 x 60 matrix? You mention "blocks of 20", so I thought you were looking for a 20 x 1350 matrix as the output.  

 

If N is the number of rows in the original matrix and p is the number of columns (is p always 3???) and k is the "block size", can you describe how to get the new matrix from the old?

IanWakeling
Barite | Level 11

I think this might do what you want, where all you need to do is pre-specify the number of blocks required.

 

proc iml;

x = shape(1:36,12,3);
print x;

nblocks = 3;
cidx = shape(1:ncol(x)#nblocks, ncol(x), nblocks);
y = shapecol(x, nrow(x)/nblocks)[ ,t(cidx)];
print y;
quit;
Alain38
Quartz | Level 8

Perfect! Thank you very much!

Rick_SAS
SAS Super FREQ

Oh, I see now. After studying the question and Ian's solution, it appears that the OP is asking for a block transpose. You can use the BTRAN function in SAS/IML to compute a block transpose. It is not clear whether the OP wants to specify the blocksize or the number of blocks. Both options are shown below:

 

proc iml;
x = shape(1:36,12,3);
blocksize = 4;
y = btran(x, blocksize, ncol(x));
print y;

x = shape(1:9000*3,0,3);     /* 9000 x 3 matrix */
nblocks = 20;
blocksize = nrow(x) / nblocks;
y = btran(x, blocksize, ncol(x));
print (dimension(y))[c={"nrow" "ncol"}];
Alain38
Quartz | Level 8

Works well too! Thank you very much!

IanWakeling
Barite | Level 11

Oh! I did it the hard way, because I didn't know that BTRAN existed.  Perhaps you should blog about it Rick, to try and get it more widely known?

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 6 replies
  • 1628 views
  • 3 likes
  • 3 in conversation