0

次の形式の入力データがあります(タブで区切られています):

(遺伝子条件値)

wnt condition1  1
wnt condition2  10
wnt condition3  15
wnt condition4  -1
bmp condition1  10
bmp condition2  inf
bmp condition3  12
bmp condition4  -1
frz condition1  -12
frz condition2  -6
frz condition3  -0.3

そして、次のようにHoHを構築しています:

#!/usr/bin/perl
use warnings;
use strict; 
use File::Slurp;
use Data::Dumper;

my @data = read_file('stack.txt');

my %hash;
foreach (@data){
    chomp;
    my ($gene, $condition, $value) = (/^(\w+)\t(\w+\d)\t(-?\d+|-?inf)/);
    $hash{$gene}{$condition} = $value;
}

HoH をループして、各遺伝子について、その遺伝子のすべての値が正 (たとえば 10) または負 (-3) のいずれかである場合に値を出力します。上記のデータでは、次のように印刷するだけです。

frz condition1  -12
frz condition2  -6
frz condition3  -0.3

他の両方の遺伝子には、正と負の両方の値を持つ条件が含まれているため:

wnt condition1  1
wnt condition2  10
wnt condition3  15
wnt condition4  -1 # discrepancy

bmp condition1  10
bmp condition2  inf
bmp condition3  12
bmp condition4  -1 # discrepancy 

次のようにループできますが、1 つの HoH 値とその遺伝子条件キー コンボの「次の」値を比較する方法がわかりません。

for my $gene (sort keys %hash) { 
     for my $condition (sort keys %{$hash{$gene}}) {
        my $value = $hash{$gene}{$condition};
        print "$gene\t$condition\t$value\n" if $value  =~ m/-/;  # This obviously will only print out negative values. I want to compare all values here, and if they are all positive, or all negative, print them.        
    }
}

これをさらに明確にすることができれば教えてください

4

3 に答える 3

1

1 つの値を隣接する値と単独で比較する代わりに、特定の遺伝子の値のリスト全体を反復処理し、正の値と負の値の別々のカウンターをインクリメントしてから、カウントを比較して不一致が存在するかどうかを確認できます。

データが次のスキームと一致すると仮定します。

'bmp' => HASH(0x7324710)
   'condition1' => 10
   'condition2' => 'inf'
   'condition3' => 12
   'condition4' => '-1'
'frz' => HASH(0x7323c78)
   'condition1' => '-12'
   'condition2' => '-6'
   'condition3' => '-0.3'
'wnt' => HASH(0x72a5c30)
   'condition1' => 1
   'condition2' => 10
   'condition3' => 15
   'condition4' => '-1'

質問の最後のコード ブロックをこのように置き換えると、必要な結果が得られます。

for my $gene (sort keys %hash) {
    # These variables will contain:
    # - Counts of positive and negative values
    my ($pos_vals, $neg_vals) = (0, 0);
    # - A true/false value indicating whether discrepancy exists
    my $discrepant = undef;
    # - A list of the values of all conditions for a given gene
    my @values = ();

    # Collect condition values for this gene into @values
    my @values = values %{ $hash{$gene} };

    # For each such value, test for a leading - and increment
    # the positive or negative value count accordingly
    for @values { $_ =~ m/^-/ ? $neg_vals++ : $pos_vals++ };

    # If neither counter is zero (i.e. both evaluate true), then
    # a discrepancy exists; otherwise, one doesn't -- either way,
    # we put the test result in $discrepant so as to produce a
    # cleaner test in the following if statement
    $discrepant = (($pos_vals > 0) and ($neg_vals > 0));

    # In the absence of a discrepancy...
    if (not $discrepant) {
        # iterate over the conditions for this gene and print the gene
        # name, the condition name, and the value
        # NB: this is somewhat idiomatic Perl, but you'll tend to see
        # it from time to time and it's thus worth knowing about
        print "$gene\t$_\t$hash{$gene}->{$_}\n"
          foreach sort keys %{ $hash{$gene} };
    };
}

注意:これは正と負の両方の無限大を正しく処理しますが、ゼロを正として扱います。これはあなたの場合には正しくないかもしれません. データにゼロ値はありますか? もしそうなら、それらは肯定的、否定的、またはどちらでもないとして扱われるべきですか?

于 2013-10-09T18:47:13.130 に答える