【问题标题】:Get highest range from the overlapping ranges [closed]从重叠范围中获取最高范围[关闭]
【发布时间】:2019-01-06 23:08:40
【问题描述】:

我有一个包含范围的文件。我想要列表中的最高范围并删除其他小的重叠范围:

chr1A   77568   86766
chr1A   203138  204427
chr1A   204428  222994
chr1A   204428  206534
chr1A   206538  207965
chr1A   207967  213097
chr1A   213098  221111
chr1A   213098  213863
chr1A   213864  214195
chr1A   214196  221111
chr1A   221112  222994
chr1A   222995  223876
chr1A   223882  227109
chr1A   305432  314629
chr1A   323643  325976
chr1A   431741  451601
chr1A   431741  435137
chr1A   435141  436568
chr1A   436570  441700
chr1A   441701  449710
chr1A   441701  442466
chr1A   442467  442798
chr1A   442799  449710
chr1A   449711  451601

例如:

第一个和第二个范围是唯一的,因此它们被保留。

第 3 到第 11 个范围有重叠,只保留最高的一个 chr1A 204428 222994,依此类推。

我想要这样的输出:

chr1A   77568   86766
chr1A   203138  204427
chr1A   204428  222994
chr1A   222995  223876
chr1A   223882  227109
chr1A   305432  314629
chr1A   323643  325976
chr1A   431741  451601

我希望在 perl、bash 或任何其他 unix 工具中获得解决方案。谢谢

【问题讨论】:

  • 我会首先通过明确应该如何合并范围来解决这个问题。例如,我想到了这个问题: 问题:22295 223876 行:a)与上面的结合是否只有 204428 到 223876? b)如果那条线是 22293 223876 怎么办 - 那会让你留下 204428 到 223876 吗?然后我会实现一个功能来合并范围。到目前为止,您尝试过什么?
  • 您要聘请程序员吗?或者你有什么问题吗?
  • 我希望能找到解决办法……我希望明天早上有一辆新车出现在我的车库里,但我没有屏住呼吸。跨度>
  • 您需要帮助的 Perl 代码在哪里?

标签: perl unix


【解决方案1】:

这是一个蛮力方法的示例。对于每个区间,我们检查它是否包含在任何其他区间内。不用说,这可能会变得非常慢,具体取决于数据量(输入文件中的行数):

use feature qw(say);
use strict;
use warnings;

my $fn = 'input.txt';
open ( my $fh, '<', $fn ) or die "Could not open file '$fn': $!";
my @ranges;
while (my $line = <$fh> ) {
    chomp $line;
    my ( $chr, $low, $high ) = split " ", $line;
    push @ranges, {chr => $chr, range => [$low, $high]};
}
close $fh;
my @result;
RANGE: for my $i (0..$#ranges) {
    my ( $low, $high ) = @{ $ranges[$i]->{range} };
    for my $j (0..$#ranges) {
        next if $i == $j;
        my ($low2, $high2) = @{ $ranges[$j]->{range} };
        next RANGE if $low>= $low2 && $high<= $high2;
    }
    push @result, $ranges[$i];
}

for my $range (@result) {
    say join "\t", $range->{chr}, @{ $range->{range} };
}

输出

chr1A   77568   86766
chr1A   203138  204427
chr1A   204428  222994
chr1A   222995  223876
chr1A   223882  227109
chr1A   305432  314629
chr1A   323643  325976
chr1A   431741  451601

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    相关资源
    最近更新 更多