我有一个文件,我必须从中获取每个查询并检查 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] }