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

#arrays #perl #hash #dna-sequence

#массивы #perl — язык программирования #хэш #последовательность днк #perl #dna-sequence

Вопрос:

У меня есть хэш с именем %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]nn";
}
  

Выходной сигнал

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


T

G

A

T

T
  

Ответ №1:

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

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

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

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

Ответ №2:

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

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

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

 print "@{ $id2seq{$id} }nn";
  

Полным примером может быть:

 #!/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
  

Ответ №3:

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

 $id2seq{$id}[3]nn";
  

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

Комментарии:

1. Я согласен с Dada.