我正在尝试从9列gff3文件中删除重叠区域。
**Input file:**
scaffold591 Source gene 3322458 3376057 0.41 - . ID=g24007
scaffold591 Source transcript 3322458 3376057 0.41 - . ID=g24007.t1;Parent=g24007
scaffold591 Source transcription_end_site 3322458 3322458 . - . Parent=g24007.t1
scaffold591 Source gene 3322500 3346055 0.41 - . ID=g24007
scaffold591 Source transcript 3322500 3346055 0.41 - . ID=g24007.t1;Parent=g24007
scaffold591 Source transcription_end_site 3322500 3322500 . - . Parent=g24007.t1
scaffold591 Source gene 3377307 3513095 0.46 + . ID=g24008
scaffold591 Source transcript 3377307 3513095 0.41 + . ID=g24008.t1;Parent=g24008
scaffold591 Source transcription_end_site 3377307 3377307 . + . Parent=g24008.t1
这里我试图仅比较具有相同链“基因”的行,即“ - ”或“+”(第7列)。
例如第1行和第4行。
scaffold591 Source gene 3322458 3376057 0.41 - . ID=g24007
scaffold591 Source gene 3322500 3346055 0.41 - . ID=g24007
它们是来自相同支架的“基因”和相同的“ - ”链(第7列)。 row4坐标(第4列和第5列)位于第1行坐标的范围内。在这种情况下,我的代码应该删除重叠的行4并保留具有更大范围的row1。
**My expected output:**
scaffold591 Source gene 3322458 3376057 0.41 - . ID=g24007
scaffold591 Source transcript 3322458 3376057 0.41 - . ID=g24007.t1;Parent=g24007
scaffold591 Source transcription_end_site 3322458 3322458 . - . Parent=g24007.t1
scaffold591 Source gene 3377307 3513095 0.46 + . ID=g24008
scaffold591 Source transcript 3377307 3513095 0.41 + . ID=g24007.t1;Parent=g24008
scaffold591 Source transcription_end_site 3377307 3377307 . + . Parent=g24008.t1
我的代码打印row1及其后续行两次
My code:
#!/usr/bin/perl
use warnings;
use strict;
use List::Util qw{ max };
open (IN, "<scaffold_sample.txt");
my $previous_seqid ="";
my $previous_strand;
my $previous_start;
my $previous_end;
my @gff;
my @tmp;
while (<IN>)
{
chomp;
my ($seqid,$source, $region, $start, $end, $score, $strand, $frame, $attribute) = split ("\t",$_);
@gff = ($seqid,$source, $region, $start, $end, $score, $strand, $frame, $attribute);
if ($seqid eq $previous_seqid && $strand eq $previous_strand && $region eq 'gene')
{
if($start < $previous_end && $end < $previous_end)
{
@gff = @tmp;
$previous_seqid = $gff[0];
$previous_strand = $gff[6];
$previous_start = $gff[3];
$previous_end = $gff[4];
print join "\t",@gff;
print "\n";
}
else
{
@tmp = @gff;
}
}
else
{
@tmp = ($seqid,$source, $region, $start, $end, $score, $strand, $frame, $attribute);
$previous_seqid = $seqid;
$previous_strand = $strand;
$previous_start = $start;
$previous_end = $end;
print join "\t",@tmp;
print "\n";
}
}
请帮忙。
答案 0 :(得分:1)
这是一个有趣的问题。您想要对行进行重复数据删除,但(我认为)如果您在文件中稍后找到更大的范围,则需要在找到原始较小范围的位置输出此大范围。
说实话,我没有看你的解决方案,而是从头开始。
我使用了两种数据结构。 %line_data
包含我们处理的行的详细信息。它是一个多级哈希,键入seqid,strand和region。如果新记录与哈希值不匹配,那么我们首次将seqid,strand和region组合在一起。如果新记录确实匹配,那么我们之前已经看过这个组合,我们计算出两者中哪一个具有最大范围并在必要时覆盖。
然后是@lines
,其中包含我们要输出的数据。它包含对%line_data
中哈希的引用。当发现更大的范围时,需要一些保持更新的房屋保养。
所以这就是我最终的结果。它为您的输入提供了正确的输出,但我不知道它是否会在更多变化的输入上中断。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my @lines;
my %line_data;
# Column names (for use as hash keys)
my @cols = qw[seqid source region start end score strand frame attribute];
# Store the input data in DATA for easier testing
while (<DATA>) {
my %record;
# Split a record into a hash
@record{@cols} = split;
# If this key combination exists...
if (exists $line_data{$record{seqid}}{$record{strand}}{$record{region}}) {
# Get the previous record with these keys...
my $prev = $line_data{$record{seqid}}{$record{strand}}{$record{region}};
# See if the new range is larger...
if ($record{start} > $prev->{start} and $record{end} > $prev->{end}) {
# If so, overwrite it.
$line_data{$record{seqid}}{$record{strand}}{$record{region}} = \%record;
$lines[$prev->{pos}] = \%record;
$record{post} = $prev->{pos};
}
} else {
# We haven't seen this key combination before.
# So just store it.
$line_data{$record{seqid}}{$record{strand}}{$record{region}} = \%record;
push @lines, \%record;
$record{pos} = $#lines;
}
}
# Having processed the data, we walk the @lines array,
# de-referencing the hash and joining the values with a space.
foreach (@lines) {
say join ' ', @$_{@cols};
}
__DATA__
scaffold591 Source gene 3322458 3376057 0.41 - . ID=g24007
scaffold591 Source transcript 3322458 3376057 0.41 - . ID=g24007.t1;Parent=g24007
scaffold591 Source transcription_end_site 3322458 3322458 . - . Parent=g24007.t1
scaffold591 Source gene 3322500 3346055 0.41 - . ID=g24007
scaffold591 Source transcript 3322500 3346055 0.41 - . ID=g24007.t1;Parent=g24007
scaffold591 Source transcription_end_site 3322500 3322500 . - . Parent=g24007.t1
scaffold591 Source gene 3377307 3513095 0.46 + . ID=g24008
scaffold591 Source transcript 3377307 3513095 0.41 + . ID=g24008.t1;Parent=g24008
scaffold591 Source transcription_end_site 3377307 3377307 . + . Parent=g24008.t1