Создание хэша массивов для последовательностей ДНК, Perl - PullRequest
0 голосов
/ 23 марта 2019

У меня есть хеш с именем %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

Ответы [ 3 ]

0 голосов
/ 23 марта 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
0 голосов
/ 23 марта 2019

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

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

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

0 голосов
/ 23 марта 2019

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

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

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

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

...