2

私は2つのファイルを持っています。1 つは一意のリストで構成され、もう 1 つは名前と年齢の重複リストです。

例えば

File1:      File2:
Gaia        Gaia 3
Matt        Matt 12
Jane        Gaia 89
            Reuben 4

私の目的は、File1 と File2 を一致させ、それぞれの名前の最高年齢を取得することです。これまでのところ、以下のコードを書いています。あまりうまくいかないのは、ハッシュで同じキーが見つかった場合、より大きな値を出力することです。

提案/コメントは大歓迎です!

ありがとう!!

#!/usr/bin/perl -w
use strict;

open (FILE1, $ARGV[0] )|| die "unable to open arg1\n"; #Opens first file for comparison
open (FILE2, $ARGV[1])|| die "unable to open arg2\n"; #2nd for comparison

my @not_red = <FILE1>;
my @exonslength = <FILE2>;

#2)  Produce an Hash of File2. If the key is already in the hash, keep the couple key-          value with the highest value. Otherwise, next.

my %hash_doc2;
my @split_exons;
my $key;
my $value;

foreach my $line (@exonslength) {

    @split_exons = split "\t", $line;

    @hash_doc2 {$split_exons[0]} = ($split_exons[1]);

 if (exists $hash_doc2{$split_exons[0]}) {

    if ( $hash_doc2{$split_exons[0]} > values %hash_doc2) {

     $hash_doc2{$split_exons[0]} = ($split_exons[1]);

    } else {next;}
       }
   }

#3) grep the non redundant list of gene from the hash with the corresponding value

my @a =  grep (@not_red,%hash_doc2);
print "@a\n";
4

2 に答える 2

4

すべての値を保持する必要がありますか? そうでない場合は、最大値のみを保持できます。

@split_exons = split "\t", $line;
if (exists $hash_doc2{$slit_exons[0]}
    and $hash_doc2{$slit_exons[0]} < $split_exons[1]) {
    $hash_doc2{$split_exons[0]} = $split_exons[1];
}

あなたのコードもすべての値を保持しているわけではありません。配列をハッシュ値に格納することはできません。参照を格納する必要があります。配列に新しい値を追加するには、次のようにしpushます。

push @{ $hash_doc2{$split_exons[0]} }, $split_exons[1];

に対する数値比較の使用valuesも、あなたが考えていることをしていません。演算子は<スカラー コンテキストを課すためvalues、値の数を返します。別のオプションは、並べ替えられた値を保存し、常に最大値を要求することです。

$hash_doc2{$split_exons[0]} = [ sort @{ $hash_doc2{$split_exons[0]} }, $split_exons[1] ];
# max for $x is at $hash_doc2{$x}[-1]
于 2012-11-05T16:55:46.377 に答える
1

file2 の全体を配列に読み込む代わりに (サイズが大きいとうまくいきません)、データ ファイルを 1 行ずつループして処理することができます。

#!/usr/bin/perl

use strict;
use warnings;
use autodie;
use Data::Dumper;

open( my $nameFh, '<', $ARGV[0]);
open( my $dataFh, '<', $ARGV[1]);

my $dataHash = {};
my $processedHash = {};

while(<$dataFh>){
    chomp;
    my ( $name, $age ) = split /\s+/, $_;
    if(! defined($dataHash->{$name}) or $dataHash->{$name} < $age ){
        $dataHash->{$name} = $age
    }
}

while(<$nameFh>){
    chomp;
    $processedHash->{$_} = $dataHash->{$_} if defined $dataHash->{$_};
}

print Dumper($processedHash);
于 2012-11-05T17:00:16.443 に答える