我有一个数组,其中包含DNA序列的唯一ID(数字)。我把我的DNA序列放在哈希中,这样每个键都包含一个描述性的标题,它的值就是DNA序列。此列表中的每个标头都包含基因信息,并以其唯一ID号作为后缀:
唯一ID:14272
标题(散列键):PREDICTEDXenopusSiluranatropicalishypotheticalproteinLOCLOCmRNA14272
序列(哈希值):ATGGGTC ......
我想遍历每个唯一ID并查看它是否与每个标头末尾的数字(散列键)匹配,如果是,则将散列键+值打印到文件中。到目前为止,我有这个:
my %hash;
@hash{@hash_index} = @hash_seq;
foreach $hash_index (sort keys %hash) {
for ($i=0; $i <= $#scaffoldnames; $i++) {
if ($hash_index =~ /$scaffoldnames[$i]/) {
print GENE_ID "$hash_index\n$hash{$hash_index}\n";
}
}
}
close(GENE_ID);
其中唯一ID包含在@scaffoldnames中。
这不起作用!我不确定如何最好地遍历散列和数组以找到匹配。
我将在下面展开:
上游代码:
foreach(@scaffoldnames) {
s/[^0-9]*//g;
} #Remove all non-numerics
my @genes = read_file('splice.txt'); #Splice.txt is a fasta file
my $hash_index = '';
my $hash_seq = '';
foreach(@genes){
if (/^>/){
my $head = $_;
$hash_index .= $head; #Collect all heads for hash
}
else {
my $sequence = $_;
$hash_seq .= $sequence; #Collect all sequences for hash
}
}
my @hash_index = split(/\n/,$hash_index); #element[0]=head1, element[1]=head2
my @hash_seq = split(/\n/, $hash_seq); #element[0]=seq1, element[1]=seq2
my %hash; # Make hash from both arrays - heads as keys, seqs as values
@hash{@hash_index} = @hash_seq;
foreach $hash_index (sort keys %hash) {
for ($i=0; $i <= $#scaffoldnames; $i++) {
if ($hash_index =~ /$scaffoldnames[$i]$/) {
print GENE_ID "$hash_index\n$hash{$hash_index}\n";
}
}
}
close(GENE_ID);
我试图分离由cuffdiff(RNA-Seq)输出的所有不同表达的基因(通过唯一ID),并将它们与它们来自的支架(在这种情况下表达的序列)相关联。
因此我希望我可以隔离每个唯一ID并搜索原始的fasta文件,以提取它匹配的标头及其关联的序列。
答案 0 :(得分:4)
您似乎错过了哈希点:它们习惯于按键索引您的数据,这样您就可以一步访问相关信息,就像使用数组一样。循环遍历每个哈希元素都会破坏这一点。例如,你不会写
my $value;
for my $i (0 .. $#data) {
$value = $data[i] if $i == 5;
}
你只需要这样做
my $value = $data[5];
如果没有更多关于您的信息来源的信息以及您想要的确切内容,很难提供帮助,但此代码应该有所帮助。
我使用了单元素数组,我认为它看起来就像你正在使用的那样,并使用ID构建了一个哈希,它将两个标题和序列索引为一个双元素数组(标题的尾随数字)作为键。您可以使用14272
查找ID $hash{14272}
的信息。标头为$hash{14272}[0]
,序列为$hash{14272}[1]
如果您提供更多有关您情况的指示,我们可以为您提供进一步的帮助。
use strict;
use warnings;
my @hash_index = ('PREDICTEDXenopusSiluranatropicalishypotheticalproteinLOCLOCmRNA14272');
my @hash_seq = ('ATGGGTC...');
my @scaffoldnames = (14272);
my %hash = map {
my ($key) = $hash_index[$_] =~ /(\d+)\z/;
$key => [ $hash_index[$_], $hash_seq[$_] ];
} 0 .. $#hash_index;
open my $gene_fh, '>', 'gene_id.txt' or die $!;
for my $name (@scaffoldnames) {
next unless my $info = $hash{$name};
printf $gene_fh "%s\n%s\n", @$info;
}
close $gene_fh;
<强>更新强>
从您发布的新代码看起来您可以使用此代码替换该部分。
它的工作原理是从它找到的每个序列头中获取尾随数字,并使用它作为键来选择要附加数据的哈希元素。哈希值是标题和序列,都在一个字符串中。如果您有理由将它们分开,请告诉我。
foreach (@scaffoldnames) {
s/\D+//g;
} # Remove all non-numerics
open my $splice_fh, '<', 'splice.txt' or die $!; # splice.txt is a FASTA file
my %sequences;
my $id;
while (<$splice_fh>) {
($id) = /(\d+)$/ if /^>/;
$sequences{$id} .= $_ if $id;
}
for my $id (@scaffoldnames) {
if (my $sequence = $sequences{$id}) {
print GENE_ID $sequence;
}
}