【问题标题】:Perl - how to compare values of array with hash tablePerl - 如何将数组的值与哈希表进行比较
【发布时间】:2015-05-13 11:50:24
【问题描述】:

新的 Perl 用户。

我正在尝试从存储在变量$blast_results 中的一些制表符分隔的数据创建一个哈希表,其中第一列作为键。然后我想将数组@filenames 中的值与哈希表中的键进行比较。如果在哈希键中找到数组值,我想打印出$blast_results 的重新排序结构,如果数组值不在哈希中,我想打印出该值后跟'No Result Found '。

这是我目前所拥有的,我认为哈希表不正确:

#!/usr/bin/env perl

use strict;
use warnings;
use Data:Dumper;

#create variable to mimic blast results
my $blast_results = "file1.ab1  9   350 0.0 449 418 418 403479  403042  567
file3.ab1   2   833 0.0 895 877 877 3717226 3718105 984";

#create array to mimic filename array
my @filenames = ("file1.ab1", "file2.ab1", "file3.ab1");

#header for file
my $header = "Query\tSeq_length\tTarget found\tScore (Bits)\tExpect(E-value)\tAlign-length\tIdentities\tPositives\tChr\tStart\tEnd\n";

#initialize hash
my %hash;
#split blast results into array
my @row = split(/\s+/, $blast_results);
$hash{$row[0]}=$_;
print $header;
foreach my $file (@filenames){
    ## If this filename has an associated entry in the hash, print it in a re-ordered format
    if(defined($hash{$file})){
        print "$row[0]\t$row[9]\t$row[1]:$row[7]-$row[8]\t$row[2]\t$row[3]\t$row[4]\t$row[5]\t$row[6]\t$row[1]\t$row[7]\t$row[8]\n";
        }
    ## If not, print this.
    else{
        print "$file\t0\tNo Blast Results: Sequencing Rxn Failed\n";
        }
    }
print "-----------------------------------\n";      
print "$blast_results\n"; #test what results look like
print "-----------------------------------\n"; 
print "$row[0]\t$row[1]\n"; #test if array is getting split correctly
print "-----------------------------------\n"; 
print "$filenames[2]\n"; #test if other array present
print "-----------------------------------\n";
print Dumper(\%hash);  #print out hash table

此脚本的结果是(@filenames 数组与哈希不匹配且哈希不包含所有数据):

Query   Seq_length  Target found    Score (Bits)    Expect(E-value) Align-length    Identities  Positives   Chr Start   End
file1.ab1   0   No Blast Results: Sequencing Rxn Failed
file2.ab1   0   No Blast Results: Sequencing Rxn Failed
file3.ab1   0   No Blast Results: Sequencing Rxn Failed
-----------------------------------
file1.ab1   9   350 0.0 449 418 418 403479  403042  567
file3.ab1   2   833 0.0 895 877 877 3717226 3718105 984
-----------------------------------
file1.ab1   9
-----------------------------------
file3.ab1
-----------------------------------
$VAR1 = {
      'file1.ab1' => undef
        };

【问题讨论】:

    标签: perl


    【解决方案1】:

    你在这里做的很奇怪:

    my %hash;
    #split blast results into array
    my @row = split(/\s+/, $blast_results);
    $hash{$row[0]}=$_;
    

    您的哈希将有一个键 - 'file1.ab1' 并且...我现在看不到 $_ 会是什么,但几乎可以肯定它是您想要的。 (从你最后的转储器输出来看,它是undef。)

    您绝不会将任何其他内容放入此哈希中,这就是您获得结果的原因。

    blast_results 通常会从文件中读取吗?

    如果是这样,这样的事情可能会起作用:

    use strict;
    use warnings;
    use Data::Dumper;
    my %hash;
    
    while (<DATA>) {
        my @line     = split;
        my $filename = shift(@line);
        $hash{$filename} = join( " ", @line );
    }
    
    print Dumper \%hash;
    
    
    __DATA__
    file1.ab1  9   350 0.0 449 418 418 403479  403042  567
    file3.ab1   2   833 0.0 895 877 877 3717226 3718105 984
    

    如果您是从命令中获取结果 - 为什么不尝试:

    open ( my $blast_results, "|-", "blastn -query test.fa -outfmt 6" );
    while ( <$blast_results> ) { 
        #parse line into hash
    }
    

    【讨论】:

    • 是的,我试图修改从文件加载散列的内容。但我认为最后只写文件可能会更好。真正的脚本运行像这样的命令行函数my $blast_result = blastn -query test.fa -outfmt 6; 所以我认为可以使用变量中的输出来创建一个哈希,然后按照我想要的方式处理文本文件。
    • 好的。那么可能是open 的工作,所以你可以逐行进行。见编辑。
    • 所以我在运行带有反引号的命令行程序,但是使用 open 可以让我逐行读取哈希表?
    • 是的。像这样打开会打开一个文件句柄,就像STDIN - 您可以一次读取一行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多