matiastofteby
matiastofteby

Reputation: 431

How to sort parts of table in Matlab?

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

Answers (3)

rahnema1
rahnema1

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

gnovice
gnovice

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

OmG
OmG

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

Related Questions