Создание хэша массивов последовательностей ДНК, Perl

У меня есть хеш с именем %id2seq, который содержит строки последовательностей ДНК, на которые ссылается ключ $id. Я хочу иметь возможность манипулировать последовательностями ДНК, используя позицию в строке в качестве ссылки. Например, если бы моя последовательность ДНК была ACGTG, моя $id была бы Sequence 1, моя $id2seq{'Sequence 1'} была бы ACGTG, а моя "теоретическая" $id2seq{'Sequence 1'}[3] была бы G. Я пытаюсь создать хэш массивов для этого, но получаю странный вывод (см. вывод ниже). Я почти уверен, что это просто мое форматирование. Любой вклад полезен, и я заранее ценю.

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

>Sequence 1
TCAGAACCAGTTATAAATTTATCATTTCCTTCTCCACTCCT
>Sequence 2
CCCACGCAGCCGCCCTCCTCCCCGGTCACTGACTGGTCCTG
>Sequence 3
TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG

Вот фрагмент моей попытки на данный момент. (У меня есть хеш-таблица, которая обращается к файлу с закомментированными последовательностями ДНК):

use strict;
use warnings;

print "Please enter the filename of the fasta sequence data: ";
my $filename1 = <STDIN>;

#Remove newline from file
chomp $filename1;

#Open the file and store each dna seq in hash
my %id2seq = ();
my $id = '';
open (FILE, '<', $filename1) or die "Cannot open $filename1.",$!;
my $dna;
while (<FILE>)
{
    if($_ =~ /^>(.+)/)
    {
        $id = $1;
    }
    else
    {
        ## $id2seq{$id} = $_; used to create hash table
        @seqs = split '', $_;
        $id2seq{$id} = [ @seqs ];
    }
}
close FILE;
foreach $id (keys %id2seq)
{
    print "$id2seq{$id}[@seqs]\n\n";
}

Выход

Use of unitialized value in concatenation (.) or string at line 37.


T

G

A

T

T

person William    schedule 23.03.2019    source источник


Ответы (3)


@seqs содержит символы из последней последовательности. $id2seq{$id}[@seqs] на самом деле означает $id2seq{$id}[N], где N — длина последней последовательности. Таким образом, вы печатаете только один символ из каждой последовательности и получаете предупреждение, если эта последовательность короче последней.

Если вы print только для отладки, проще:

use Data::Dumper;
print Dumper(\%id2seq);

В противном случае вам придется самостоятельно перебирать $id2seq{$id} во вложенном цикле.

person UjinT34    schedule 23.03.2019

Эта строка неверна:

print "$id2seq{$id}[@seqs]\n\n";

$id2seq{$id} - это ссылка на массив, поэтому правильный способ его печати будет

print "@{ $id2seq{$id} }\n\n";

Полный пример:

#!/usr/bin/perl
use warnings;
use strict;

my $current_id;
my %id2seq;
while (<DATA>) {
    chomp;
    if (/^>(.+)/) {
        $current_id = $1;
    } else {
        $id2seq{$current_id} = [ split(//) ];
    }
}

print "@{ $_ }\n" foreach (values %id2seq);

exit 0;

__DATA__
>Sequence 1
TCAGAACCAGTTATAAATTTATCATTTCCTTCTCCACTCCT
>Sequence 2
CCCACGCAGCCGCCCTCCTCCCCGGTCACTGACTGGTCCTG
>Sequence 3
TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG

Тестовый забег:

$ perl dummy.pl
T C G A C C C T C T G G A A C C T A T C A G G G A C C A C A G T C A G C C A G G C A A G
C C C A C G C A G C C G C C C T C C T C C C C G G T C A C T G A C T G G T C C T G
T C A G A A C C A G T T A T A A A T T T A T C A T T T C C T T C T C C A C T C C T
person Stefan Becker    schedule 23.03.2019

Вам нужно распечатать

$id2seq{$id}[3]\n\n";

Чтобы получить четвертое значение. Кроме того, вы никогда не определяли @seqs с «my» настолько строго, а предупреждения жалуются, поэтому «Использование унифицированного значения в конкатенации (.) или строки в строке 37.». Либо удалите предупреждения/строгие, либо определите @seqs

person kmast    schedule 23.03.2019
comment
Я согласен с Дада. - person ikegami; 24.03.2019