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,
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;
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?
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;
Perfect! Thank you very much!
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"}];
Works well too! Thank you very much!
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?
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!
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.