Как сгруппировать серии последовательных номеров в Perl - PullRequest
1 голос
/ 25 апреля 2011

У меня есть ввод данных, который выглядит следующим образом:

seq   75      T   G   - 
seq   3185    A   R   +
seq   3382    A   R   +
seq   4923    C   -   + *
seq   4924    C   -   + *
seq   4925    T   -   + *
seq   5252    A   W   +
seq   7400    T   C   -
seq   16710   C   -   - #
seq   18248   T   C   -
seq   18962   C   -   + *
seq   18963   A   -   + *
seq   18964   T   -   + *
seq   18965   A   -   + *
seq   19566   A   M   +

The input above is already sorted at 2nd column.

Что я хочу сделать, это:

  1. Обрабатывать только те строки, где 4-й столбец - «-».
  2. Если эти строки содержат последовательные позиции (2-й столбец), сгруппируйте их
  3. Представьте их как одну новую строку с самой низкой позицией в качестве новой позиции и объединением сгруппированных букв в качестве новых строк.

Следовательно, мы ожидаем получить этот вывод:

seq   75      T   G   -   
seq   3185    A   R   +
seq   3382    A   R   +
seq   4923    CCT   -   + **
seq   5252    A   W   +
seq   7400    T   C   -
seq   16710   C   -   - #
seq   18248   T   C   -
seq   18962   CATA   -   + **
seq   19566   A   M   +

** Are the new lines/string formed by * line in first list (input)
# line is kept as it is because there is no consecutive position after that.

Я застрял в следующей логике, не знаю, как поступить:

while ( <> ) {
    chomp;

    my @els = split(/\s+/,$_);

    # Process indel
    my @temp = ();
    if ( $els[3] eq "-"  ) {
        push @temp, $_;
    }

     # How can I group them appropriately.
     print Dumper \@temp ;

     # And print accordingly to input ordering

}

1 Ответ

5 голосов
/ 25 апреля 2011

Это вариант отчета об отключении управления. Этот код, кажется, делает работу:

use strict;
use warnings;

my($prev) = -100;
my($grp0) = $prev;
my($col2, $col4);

sub print_group
{
    my($grp0, $col2, $col3, $col4) = @_;
    printf "seq   %-5d  %-4s  %s  %s\n", $grp0, $col2, $col3, $col4
        if ($grp0 > 0);
}

while (<>)
{
    chomp;
    my @els = split(/\s+/,$_);
    if ($els[3] ne "-")
    {
        print_group($grp0,   $col2,   "-",     $col4);
        print_group($els[1], $els[2], $els[3], $els[4]);
        $prev = -100;
        $grp0 = -100;
        $col2 = "";
        $col4 = "";
    }
    elsif ($els[1] == $prev + 1)
    {
        $grp0  = $prev if $grp0 < 0;
        $prev  = $els[1];
        $col2 .= $els[2];
        $col4  = $els[4];
    }
    else
    {
        print_group($grp0, $col2, "-", $col4);
        $prev = $els[1];
        $grp0 = $els[1];
        $col2 = $els[2];
        $col4 = $els[4];
    }
}

print_group($grp0, $col2, $col4);

Пример вывода:

seq   75     T     G  -
seq   3185   A     R  +
seq   3382   A     R  +
seq   4923   CCT   -  +
seq   5252   A     W  +
seq   7400   T     C  -
seq   16710  C     -  -
seq   18248  T     C  -
seq   18962  CATA  -  +
seq   19566  A     M  +

Это более равномерный вывод, чем в предыдущем издании, но основная логика очень похожа на предыдущую. Выходные данные всегда генерируются одной и той же функцией, поэтому все максимально равномерно.

Может быть очень трудно получить правильные условия - потребовалось несколько (слишком много) итераций, чтобы получить этот код для получения ожидаемого результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...