1

染色体:開始-終了という形式のゲノム位置のリストがあります

例えば

chr1:100-110
chr1:1000-1100
chr1:200-300
chr10:100-200
chr2:100-200
chrX:100-200

これを取得するために、これを染色体番号と数値の開始位置で並べ替えたい:

chr1:100-110
chr1:200-300
chr1:1000-1100
chr2:100-200
chr10:100-200
chrX:100-200

perlでこれを行うための効果的で効率的な方法は何ですか?

4

5 に答える 5

1

次の順序で並べ替えたいようです。

  1. 染色体番号別
  2. 次に、開始位置によって
  3. 次に(おそらく)終了位置で。

したがって、おそらく次のようなカスタムソートです。

use strict;
use warnings;

print sort {
    my @a = split /chr|:|-/, $a;
    my @b = split /chr|:|-/, $b;
    "$a[1]$b[1]" !~ /\D/ ? $a[1] <=> $b[1] : $a[1] cmp $b[1]
      or $a[2] <=> $b[2]
      or $a[3] <=> $b[3]
} <DATA>;

__DATA__
chr1:100-110
chr1:1000-1100
chr1:200-300
chr10:100-200
chr2:100-200
chrX:100-200
chrY:100-200
chrX:1-100
chr10:100-150

出力:

chr1:100-110
chr1:200-300
chr1:1000-1100
chr2:100-200
chr10:100-150
chr10:100-200
chrX:1-100
chrX:100-200
chrY:100-200
于 2014-07-18T15:15:01.490 に答える
1

モジュールを使用するだけですSort::Keys::Natural

use strict;
use warnings;

use Sort::Key::Natural qw(natsort);

print natsort <DATA>;

__DATA__
chr1:100-110
chr1:1000-1100
chr1:200-300
chr10:100-200
chr2:100-200
chrX:100-200
chrY:100-200
chrX:1-100
chr10:100-150

出力:

chr1:100-110
chr1:200-300
chr1:1000-1100
chr2:100-200
chr10:100-150
chr10:100-200
chrX:1-100
chrX:100-200
chrY:100-200
于 2014-08-11T21:43:23.527 に答える
1

カスタム コンパレータを指定することで、これを並べ替えることができます。並べ替えキーとして 2 レベルの値が必要なようです。そのため、カスタム コンパレーターは行のキーを取得し、それを比較します。

# You want karyotypical sorting on the first element,
# so set up this hash with an appropriate normalized value
# per available input:

my %karyotypical_sort = (
    1 => 1,
    ...
    X => 100,
);

sub row_to_sortable {
    my $row = shift;
    $row =~ /chr(.+):(\d+)-/; # assuming match here! Be careful
    return [$karyotypical_sort{$1}, $2];
}

sub sortable_compare {
    my ($one, $two) = @_;

    return $one->[0] <=> $two->[0] || $one->[1] <=> $two->[1];
    # If first comparison returns 0 then try the second
}

@lines = ...

print join "\n", sort {
    sortable_compare(row_to_sortable($a), row_to_sortable($b))
} @lines;

計算は少し面倒なので (文字列の操作は無料ではありません)、おそらく大量のデータ (ゲノム!) を扱っているため、 Schwartzian Transformを実行するとパフォーマンスが向上することに気付くでしょう。これは、行のソート キーを事前に計算し、それを使用してソートし、最後に追加データを削除することによって実行されます。

@st_lines = map { [ row_to_sortable($_), $_ ] } @lines;
@sorted_st_lines = sort { sortable_compare($a->[0], $b->[0]) } @st_lines;
@sorted_lines = map { $_->[1] } @sorted_st_lines;

または組み合わせ:

print join "\n",
    map { $_->[1] }
    sort { sortable_compare($a->[0], $b->[0]) }
    map { [ row_to_sortable($_), $_ ] } @lines;
于 2014-07-18T15:07:59.990 に答える
0

同様の質問があり、ここで回答されています。

英数字ソートperlを実行するには?

あなたが探している可能性が高いのは、を使用するような一般的な数値ソートsort -gです。

于 2014-07-22T00:41:44.863 に答える
0

上記の入力を指定してテキスト ファイルを取得する次のスクリプトで、このようなことを行うことができます。染色体番号の並べ替えは、純粋に語彙的または数値的ではないため、少し変更する必要があります。しかし、私が以下に持っているものを微調整できると確信しています:

use strict;

my %chromosomes;

while(<>){
        if ($_ =~ /^chr(\w+):(\d+)-\d+$/)
        {
                my $chr_num = $1;
                my $chr_start = $2;
                $chromosomes{$1}{$2} = $_;
        }
}

my @chr_nums = sort(keys(%chromosomes));
foreach my $chr_num (@chr_nums) {
        my @chr_starts = sort { $a <=> $b }(keys(%{$chromosomes{$chr_num}}));
         foreach my $chr_start (@chr_starts) {
                print "$chromosomes{$chr_num}{$chr_start}";
        }
 }

1;
于 2014-07-18T15:15:40.163 に答える