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?
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.