1

特定のデータ ビニングを考慮して、2 つのファイルを比較して、いくつの異なるオブジェクトがあるかをカウントする必要があります。1 つ目は 3 列のファイル (ここでtest_counter.txtは ) で、報告された ID ペア (ID は で区切られて|います) であり、各 ID ペアには関連付けられた値があります。別のファイル ( list.pl) には、ID の単純なリストがあり、$id{"ID1"} = 1;. したがって、必要なのはtest_counter.txt、各ビンのファイルにあるさまざまな ID をカウントし (間隔は 0.1 に等しい必要があります)、繰り返しなしで (ID がビンに 2 回存在する場合はそれをカウントしたいということです) 1回だけ)。3 列のファイル ( test_counter.txt) は次のようになります。

d|a -0.1412
a|a -0.1526
d|a 0.12
c|b 0.16596
b|a 0.221
c|a 0.21123
d|b 0.388
c|b 0.35
b|d 0.412
d|a 0.5236
d|c 0.565
b|a 0.6174
a|c 0.65
c|d 0.678

list.plファイルは次のようなものです。

$id{"a"} = 1;
$id{"b"} = 1;
$id{"c"} = 1;
$id{"d"} = 1;

私の望む出力は次のようなものです:

-0.9 
-0.8 
-0.7 
-0.6 
-0.5 
-0.4 
-0.3 
-0.2 
-0.1 2
0 
0.1 4
0.2 3
0.3 3
0.4 2
0.5 3
0.6 4
0.7 
0.8 
0.9 

そして私のコードは次のとおりです。

    require("id_pf.pl");
    $file = "test_counter.txt";
    open(HAN, "< $file") ||  die "not opening $file";
        @row = <HAN>;
    close(HAN);
    for($i=0;$i<=$#row;$i++) {
        chomp($row[$i]);
        ($ppi,$val) = split(/ /,$row[$i]);
        ($p1,$p2) = split(/\|/,$ppi);
        if ($val <-0.9) {
            $bin= 1;        
        } elsif ($val <-0.8) {
            $bin = 2;
        } elsif ($val <-0.7) {
                $bin = 3;
        } elsif ($val <-0.6) {
                $bin = 4;
        } elsif ($val <-0.5) {
                $bin = 5;
        } elsif ($val <-0.4) {
                $bin = 6;
        } elsif ($val <-0.3) {
                $bin = 7;
        } elsif ($val <-0.2) {
                $bin = 8;
        } elsif ($val <-0.1) {
                $bin = 9;
    } elsif ($val <-0.0) {
                $bin = 10;
        } elsif ($val <0.1) {
                $bin = 11;
        } elsif ($val <0.2) {
                $bin = 12;
        } elsif ($val <0.3) {
                $bin = 13;
        } elsif ($val <0.4) {
                $bin = 14;
        } elsif ($val <0.5) {
                $bin = 15;
        } elsif ($val <0.6) {
                $bin = 16;
        } elsif ($val <0.7) {
                $bin = 17;
        } elsif ($val <0.8) {
                $bin = 18;
        } elsif ($val <0.9) {
                $bin = 19;
    } else {
        $bin = 20;
    }
    if (($id{$p1}) || ($id{$p2})){
    $pos[$bin]++;   
} else {
        }
    }
    for ($k=1;$k<=20;$k++) {
        $bin = ($k/10)-1.05;
        print "$bin\t$pos[$k]\n";
    }

このコードを使用すると、次の(間違った)結果が得られます。

-0.9 
-0.8 
-0.7 
-0.6 
-0.5 
-0.4 
-0.3 
-0.2 
-0.1 2
0 
0.1 2
0.2 2
0.3 2
0.4 1
0.5 2
0.6 3
0.7 
0.8 
0.9 

したがって、実際には私のコードは最初の ID を読み取るだけで動作し、2 番目の ID は考慮しません。もう 1 つの間違いは、ビンに出現する回数だけ ID をカウントすることです。どんな助けでも大歓迎です!

4

1 に答える 1

3

コメントに従って編集されました。今すぐ動作するはずです。

use strict;
use warnings;
use 5.14.0;

my %hash;
while(<DATA>){
    next if /^\s*$/m; # In case if you have empty lines.
    my ($key1,$key2,$val) = /^(\w)\|(\w) ([0-9.-]+)/;
    $val = int($val*10)/10; 
    $hash{$val}{$key1}++;
    $hash{$val}{$key2}++;
}
for (-9..9){
    $_ = $_/10;
    say "$_\t",ref $hash{$_} ? scalar keys $hash{$_} : '';
}

__DATA__
d|a -0.1412
a|a -0.1526
d|a 0.12
c|b 0.16596
b|a 0.221
c|a 0.21123
d|b 0.388
c|b 0.35
b|d 0.412
d|a 0.5236
d|c 0.565
b|a 0.6174
a|c 0.65
c|d 0.678

出力:

-0.9    
-0.8    
-0.7    
-0.6    
-0.5    
-0.4    
-0.3    
-0.2    
-0.1    2
0   
0.1 4
0.2 3
0.3 3
0.4 2
0.5 3
0.6 4
0.7 
0.8 
0.9 
于 2013-10-23T09:53:03.163 に答える