#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.