各クエリを取得し、Alt_fromとAlt_toの値を確認する必要があるファイルがあります。 Alt_from と Alt_to の値が重複している場合は、スコアが最も高い行をチェックし、重複しない値と一緒にファイルに印刷します。
入力ファイル:
Sr.No query score ALIfrom ALIto
1 g1 135.2 93 231
2 g182 40.5 244 296
3 g182 45.4 247 311
4 g182 53.1 302 348
5 g182 50.6 305 362
6 g182 52.9 354 396
7 g182 24.9 357 397
8 g19 45.2 19 181
9 g19 166.8 19 208
10 g19 182.3 27 258
11 g22 94.5 46 139
12 g22 101.3 141 221
13 g22 66.7 230 353
14 g22 36.8 230 391
15 g266 57.7 47 127
16 g266 12.6 343 375
17 g266 17.8 348 375
予想出力:
Sr.No query score ALIfrom ALIto
1 g1 135.2 93 231
2 g182 40.5 244 296
4 g182 53.1 302 348
6 g182 52.9 354 396
10 g19 182.3 27 258
11 g22 94.5 46 139
12 g22 101.3 141 221
13 g22 66.7 230 353
15 g266 57.7 47 127
17 g266 17.8 348 375
Perlを試してみましたが、正しい入れ子になった値を確認しません。重複とは、たとえば、クエリg1(Sr.no 2)のAlt_fromとAlt_toの値の範囲は150〜200で、クエリg1(Sr.no 3)ではAlt_fromとAlt_toの値の範囲です。 160~190の間です。 Sr.no 3の値はSr.no 2の値の範囲に属し、これはネストされます。この場合、コードはスコアを確認し、スコアが最も高いコードを選択する必要があります。予想される出力からわかるように、Sr.no 2の行は低いスコアのために削除され、Sr.no 3の行は高いスコアのために選択されます。
ベストアンサー1
軽くテストされたPerlスクリプト:
#!/usr/bin/env perl
use strict;
use warnings;
my $header = <>;
print $header;
my $query = '';
my @store = ();
LINE: while (<>) {
my ( $line, %data );
$line = $_;
chomp;
@data{qw/sr query score from to/} = split /\s+/;
if ( $data{query} eq $query ) {
for ( my $i = @store - 1 ; $i >= 0 ; $i-- ) {
my %odata = %{ $store[$i]->[1] };
if ( $odata{to} > $data{from} and $odata{from} < $data{to} ) {
# overlap
if ( $data{score} > $odata{score} ) { splice @store, $i, 1 }
else { next LINE }
}
}
push @store, [ $line, \%data ];
}
else {
for (@store) { print $_->[0] }
@store = ( [ $line, \%data ] );
$query = $data{query};
}
}
for (@store) { print $_->[0] }