The easiest solution would be to reshape your data, sort, then permute it:
rps = 3; % rows per subgroup
B = permute(sort(reshape(A.',rps,size(A,2),[]),2),[2 1 3]);
The above results in a 3x3x2 arrays, which in my opinion are easier to work with, but if you want the output as in the example, you can do the following:
B = reshape(permute(sort(reshape(A.',rps,size(A,2),[]),2),[2 3 1]),size(A));
Alternatively, you are correct to think that splitapply
can be useful here, but it requires a bit more work.
This command works on the sample data and should also work on your full dataset:
b = cell2mat( splitapply( @(x){sort(x,2).'}, A.', repelem( 1:size(A,1)/rps, rps ) ).' );
I'll explain what this does:
repelem( 1:size(A,1)/rps, rps )
returns a row vector of groups. The amount of groups is the total amount of rows divided by the group size. (For good measure, there should be an assertion that this is divisible with no remainder).
splitapply( @(x){sort(x,2).'}, ...
since splitapply
has to return a scalar object per group, it needs to be told that the output is a cell so that it can return a matrix. (This might not be the best explanation, but if you attempt to run it w/o a cell output, you will get the following error:
The function 'sort' returned a non-scalar value when applied to the 1st group of data.
To compute nonscalar values for each group, create an anonymous function to return each value in a scalar cell:
@(x1){sort(x1)}
I perform several transpose operations since this is what splitapply
expects.
- I used
cell2mat
to convert the output cells back to a numeric array.