in reply to Sort a matrix by row

G'day soblanc,

The general solution for this is to do a primary sort and then, when primary elements are the same, do a secondary sort. The primary and secondary sorts are separated by a || operator. A typical application would be to sort on "lastname" then, for those with the same "lastname", sort on "firstname".

With the data you've presented, the aN values are already sorted within tN values; there's no way to use that to show how this works.

I ran three tests:

I manually changed @matrix for each run. Here's the final code.

#!/usr/bin/env perl use strict; use warnings; my @matrix = ( [qw{t1 t1 t2 t2 t1 t2}], [qw{a2 a1 a3 a2 a3 a1}], [qw{mis mis mis mis del del}], ); print "Original\n"; print_matrix(\@matrix); my @sorted_indices = sort { $matrix[0][$a] cmp $matrix[0][$b] || $matrix[1][$a] cmp $matrix[1][$b] } 0 .. $#{$matrix[0]}; print "Sorted indices\n"; print "@sorted_indices\n"; sub print_matrix { my ($matrix) = @_; for my $row (0 .. $#$matrix) { print join(' ', @{$matrix[$row]}), "\n"; } }

Here's the output for the three runs:

ken@titan ~/tmp $ ./pm_11146491_sort_matrix.pl Original t1 t1 t2 t2 t1 t2 a1 a2 a1 a2 a3 a3 mis mis mis mis del del Sorted indices 0 1 4 2 3 5 ken@titan ~/tmp $ ./pm_11146491_sort_matrix.pl Original t1 t1 t2 t2 t1 t2 a1 a2 a3 a2 a3 a1 mis mis mis mis del del Sorted indices 0 1 4 5 3 2 ken@titan ~/tmp $ ./pm_11146491_sort_matrix.pl Original t1 t1 t2 t2 t1 t2 a2 a1 a3 a2 a3 a1 mis mis mis mis del del Sorted indices 1 0 4 5 3 2

Armed with the sorted indices, I'll assume you can create sorted matrices. If you encounter problems with this, show us what you tried and where you encountered difficulties — we can provide further help when we know what problem you're having.

— Ken

Replies are listed 'Best First'.
Re^2: Sort a matrix by row
by soblanc (Acolyte) on Aug 30, 2022 at 14:17 UTC

    Thank you for your answers!

    Indeed, working with indexes do the job, because in the end I just want to retrieve the array "effects" in the right order, and not necessarily reconstruct the matrix.

    So with my example, this code works fine :

    my @idx = sort { $matrix[0][$a] cmp $matrix[0][$b] } 0..$#{$matrix[0]} +; my @effets_ord = map { $matrix[2][$_] } @idx;

    If I understood correctly, this sorts the transcript's row (attributes indexes actually) and finally I get the effects in the right order.

    This is the first step of what I aim to do.

    BUT for the second step (sort alleles) the subtlety I omit to say is that I want to order alleles according to another array, let's say for example:

    my @alleles_origin = (a2,a1,a3);

    Knowing the number of members in @alleles is the same for each transcript (t1 and t2).

    So finally, the effects in my array @effects_sorted would be in the order of : t1 then t2 (this step is ok now thanks to you guys), and also alleles in the order of @alleles_origin for t1 and t2.