Perl: вернуть максимальное процентное совпадение для строк

У меня есть последовательность ДНК, например, ATCGATCG. У меня также есть база данных последовательностей ДНК, отформатированная следующим образом:

>Name of sequence1
SEQUENCEONEEXAMPLEGATCGATC
>Name of sequence2
SEQUENCETWOEXAMPLEGATCGATC

(Таким образом, строки с нечетными номерами содержат имя, а строки с четными номерами содержат последовательность). В настоящее время я ищу идеальные совпадения между моей последовательностью и последовательностями в базе данных следующим образом (предположим, что все переменные объявлены):

my $name;
my $seq;
my $returnval = "The sequence does not match any in database";
open (my $database, "<", $db1) or die "Can't find db1";
until (eof $database){
    chomp ($name = <$database>);
    chomp ($seq = <$database>);
    if (
        index($seq, $entry) != -1
        || index($entry, $seq) != -1
    ) {
        $returnval = "The sequence matches: ". $name;
        last;
    }
}
close $database;

Есть ли способ вернуть имя последовательности с наибольшим процентом совпадения, а также процентное совпадение между записью и последовательностью в базе данных?


person Aditya J.    schedule 16.08.2016    source источник
comment
Насколько велика база данных?   -  person Zaid    schedule 16.08.2016
comment
Не уверен, что String::Approx поможет вам здесь.   -  person Zaid    schedule 16.08.2016
comment
Вы можете разбить свою строку и перейти от символа к символу, даже если это придирчиво. Что-то вроде того, что было сделано, например, в this post. Лучше найдите модуль, например Text::Fuzzy должен сделать это.   -  person zdim    schedule 16.08.2016
comment
Вы можете найти минимальное расстояние редактирования Левенштейна (и преобразовать его в проценты).   -  person Michael Carman    schedule 16.08.2016
comment
Я не думаю, что String::Approx здесь поможет, @Zaid: последовательности не все одинаковой длины. Кроме того, самая большая база данных содержит 1881 запись, то есть 3762 строки. Я попробую использовать Text::Fuzzy и text::Levenshtein, чтобы найти процентное совпадение.   -  person Aditya J.    schedule 16.08.2016
comment
Похоже, String::Similarity возвращает процент.   -  person Aditya J.    schedule 16.08.2016
comment
Я рекомендую хороший мудул, но, между прочим, не должно быть слишком сложно создать свой собственный.   -  person zdim    schedule 17.08.2016


Ответы (1)


String::Similarity возвращает сходство между строками в виде значения от 0 до 1, где 0 совершенно разные, а 1 абсолютно одинаковые.

my $entry = "AGGUUG" ;
my $returnval;
my $name;
my $seq;
my $currsim;
my $highestsim = 0;
my $highestname;
open (my $database, "<", $db1) or die "Can't find db1";
until (eof $database){
    chomp ($name = <$database>);
    chomp ($seq = <$database>);
    $currsim = similarity $entry, $seq, $highestsim;
    if ($currsim > $highestsim) {
        $highestsim = $currsim;
        $highestname = $name;
    }
}
$highestsim = $highestsim * 100;
my @names = split(/>/, $highestname);
$returnval = "This sequence matches " . $names[1] . " the best with " . $highestsim . "% similarity";
close $database;
person Aditya J.    schedule 16.08.2016
comment
Вы должны увидеть улучшение производительности, если вы передадите $highestsim в качестве третьего аргумента similarity — это приведет к тому, что сравнение прекратится, как только сходство упадет ниже заданного предела. - person Michael Carman; 17.08.2016
comment
Имеет смысл. я добавлю это - person Aditya J.; 17.08.2016