Как сравнить два текстовых файла по столбцу и вывести количество совпадений столбцов - PullRequest
0 голосов
/ 17 ноября 2011

У меня есть два файла последовательности генома с разделителями табуляции (в формате SAM), и я хотел бы сравнить их, чтобы увидеть, сколько раз определенные последовательности чтения (которые содержат одну строку) присутствуют в каждом.

Вот пример формата входного файла:

HWI-AT555:86:D0:6:2208:13551:55125       122     chr1    77028   255     94M555N7M       *       0       0       GTGCCTTCCAATTTTGTGAGTGGAGNACAAGTTCGCTAAAGCTAATGAATGATCTACCACCATGATTGAGTGTCTGAGTCGAATCAAGTGAATTGCTGTTAG   &&&(((((*****++++++++++++!!&)*++++)+++++++++++++++++++++++++*++++++++*****((((((''''''&&&&'''&&&&&&&&   NM:i:3  XS:A:+    NH:i:1

Важной частью является идентификатор чтения последовательности, который является первым столбцом (т. Е. HWI -.... 55125). Это то, что я хочу использовать для сравнения двух файлов, чтобы я мог посчитать количество дубликатов / копий.

Вот что у меня есть:

unless (@ARGV == 2) {
    print "Use as follows: perl program.pl in1.file in2.file\n";
    die;
}

my $in1 = $ARGV[0];
my $in2 = $ARGV[1];

open ONE, $in1;
open TWO, $in2;

my %hash1;
my @hit;    

while (<ONE>){
    chomp;
    my @hit = split(/\t/, $_);
    $hash1{$hit[0]}=1;
}
close ONE;

my @col;

while (<TWO>){
    chomp;
    my @col = split(/\t/, $_);
    if ($col[0] =~ /^H/){  #only valid sequence read lines start with "H"
        print "$col[0]\n" if defined($hash1{$_});   

    }
}
close TWO;

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

Я новичок в программировании, и я застрял в том, как я могу вести подсчет, когда есть совпадения во время прохождения цикла. Любая помощь будет оценена. Дайте мне знать, если я ничего не прояснил.

1 Ответ

2 голосов
/ 17 ноября 2011

Инициализируйте ваш %hash1 нулями вместо единиц:

while (<ONE>){
    chomp;
    my @hit = split(/\t/, $_);
    # Start them as "0" for "no duplicates".
    $hash1{$hit[0]} = 0;
}

Затем во втором цикле вы можете увеличить $hash1{$col[0]}:

while (<TWO>){
    chomp;
    my @col = split(/\t/, $_);
    # Increment the counter if %hash1 has what we're looking for.
    ++$hash1{$col[0]} if(exists($hash1{$col[0]}));
}

Нет необходимости проверять $col[0] =~ /^H/, поскольку %hash1 будет содержать записи только для правильных последовательностей, поэтому вы можете просто выполнить проверку exists для хэша. И вы хотите посмотреть на $hash1{$col[0]}, а не $hash1{$_}, поскольку вы сохраняете только первую часть строк в первом цикле, $_ будет иметь всю строку. Кроме того, если вы просто захватываете первое поле каждой строки, вам не нужны вызовы chomp, но они не причиняют вреда, поэтому вы можете оставить их, если хотите.

Это оставляет вас со всеми повторяющимися записями в %hash1 как записи с ненулевыми значениями, и вы можете grep из них:

my @dups = grep { $hash1{$_} > 0 } keys %hash1;

А затем отобразить их с их счетами:

for my $k (sort @dups) {
    print "$k\t$hash1{$k}\n";
}

Вы также можете проверить количество при отображении совпадений:

for my $k (sort keys %hash1) {
    print "$k\t$hash1{$k}\n" if($hash1{$k} > 0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...