Reputation: 431
I have a table in Matlab containing test data from different test persons. The test has seven video clips each with four different audio versions, which the test persons must rate on a scale from 1 to 100. Every video clip is presented twice for statistical accuracy. The test person pushes buttons 1-4 on an interface to hear the different audio versions.
My table contains the following columns (among some others that are not relevant for the question):
Test Person ID Audio Version Video Clip Rating
1 1 Forest 40
1 2 Forest 60
1 3 Forest 20
1 4 Forest 100
Now, to introduce minimal bias towards any favor of a particular button during the test, the audio versions are randomly permuted between every video clip. This means the real data will look somewhat more like this (Audio Version not sorted):
Test Person ID Audio Version Video Clip Rating
1 1 Forest 40
1 2 Forest 60
1 3 Forest 20
1 4 Forest 100
1 3 City 10
1 2 City 50
1 1 City 40
1 4 City 7
1 4 Inside 90
1 2 Inside 58
1 1 Inside 22
1 3 Inside 35
What I want to do is to: Maintain the correct order of the video clips, thus still have Forest -> City -> Inside, but have them all ordered so that is always audio version 1, 2, 3, 4:
Test Person ID Audio Version Video Clip Rating
1 1 Forest 40
1 2 Forest 60
1 3 Forest 20
1 4 Forest 100
1 1 City 40
1 2 City 50
1 3 City 10
1 4 City 7
1 1 Inside 22
1 2 Inside 58
1 3 Inside 35
1 4 Inside 90
My initial thought was to use the sortrow()
function in Matlab and then sort them ascendingly along with the video clip, but since the video clips are introduced twice at different stages of the test and I want to maintain the same sequence of the clips in the table this doesn’t work. Also the same video clips are presented to numerous different test persons.
I am using a pre-made function that has to have the data sorted in this way to perform statistical calculations on it. This function takes the Matlab data from a struct and puts it into the table via a for-loop row for row.
Because the data is put into the table via a for-loop I thought there might be a way to only sort a fixed number of rows at a time i.e row 1-4, 5-8, 9-12 and so on. Do you know if there is a way to sort only part of a table in Matlab?
Upvotes: 1
Views: 312
Reputation: 15837
Using reshape
and sort
you can do:
[~,idx]=sort(reshape(Audio_Version,4,[]));
idxtble = bsxfun(@plus,idx,0:4:(4*size(idx,2))-1);
table2 = table1(idxtble,:);
Explanation:
You can extract the audio column and reshape it to to [4 * n] matrix:
audio = reshape(Audio_Version,4,[]);
then sort columns of audio and get indexes of sorted elements:
[~,idx]=sort(audio);
Here idx
represents row numbers of the sorted elements.
Convert idx
to linear indexes of the whole column of the table:
idxtbl = bsxfun(@plus,idx,0:4:(4*size(idx,2))-1);
Reorder the table:
table2 = table1(idxtbl,:);
Upvotes: 1
Reputation: 125854
You can do this with a single call to sortrows
by creating an additional numeric column representing your fixed pattern of video presentations. This additional column will simply label each set of 4 rows with a successive integer. It can be concatenated to the beginning of the table, then you can sort by the first and third columns to get the ordering you want:
[~, index] = sortrows([table(ceil((1:size(T, 1)).'./4)) T], [1 3]);
T = T(index, :);
And the output:
T =
ID Audio Video Rating
__ _____ ________ ______
1 1 'Forest' 40
1 2 'Forest' 60
1 3 'Forest' 20
1 4 'Forest' 100
1 1 'City' 40
1 2 'City' 50
1 3 'City' 10
1 4 'City' 7
1 1 'Inside' 22
1 2 'Inside' 58
1 3 'Inside' 35
1 4 'Inside' 90
Upvotes: 2
Reputation: 18838
Just using sortrow
for the specified part of the table like the following:
table(1:4,:) = sortrow(table(1:4,:), 2);
table(4:8,:) = sortrow(table(4:8,:), 2);
table(8:12,:) = sortrow(table(8:12,:), 2);
First sort the part of the table, then replace it with that part.
Upvotes: 0