Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用perl对数据进行装箱后的元素计数_Perl - Fatal编程技术网

用perl对数据进行装箱后的元素计数

用perl对数据进行装箱后的元素计数,perl,Perl,我需要计算在比较两个文件时,考虑到一个特定的数据装箱,我有多少不同的对象。第一个是一个三列文件(此处为test_counter.txt),其中有报告的ID对(ID由|分隔),每个ID对都有一个与之关联的值。在另一个文件(list.pl)中,我有一个简单的id列表,写为$id{“ID1”}=1。 因此,我需要的是计算每个箱子中test\u counter.txt文件中的不同ID(间隔必须等于0.1),并且不重复(意味着如果箱子中有两个ID,我只想计算一次)。 三列文件(test\u counter

我需要计算在比较两个文件时,考虑到一个特定的数据装箱,我有多少不同的对象。第一个是一个三列文件(此处为
test_counter.txt
),其中有报告的ID对(ID由
|
分隔),每个ID对都有一个与之关联的值。在另一个文件(
list.pl
)中,我有一个简单的id列表,写为
$id{“ID1”}=1。
因此,我需要的是计算每个箱子中
test\u counter.txt
文件中的不同ID(间隔必须等于0.1),并且不重复(意味着如果箱子中有两个ID,我只想计算一次)。 三列文件(
test\u 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
-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 
list.pl
文件如下所示:

$id{"a"} = 1;
$id{"b"} = 1;
$id{"c"} = 1;
$id{"d"} = 1;
我想要的输出是这样的:

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 
我的代码是:

    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";
    }
实际上,我的代码只读取第一个ID,而不考虑第二个ID。另一个错误是,它计算一个ID的次数与它在垃圾箱中出现的次数相同。
欢迎任何帮助

根据评论进行编辑。现在应该可以工作了

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

对于我在这里编写的示例,您的代码运行良好,但是如果数据中的值有两个或更多的十进制数,则无法正确打印…您可以提出一些建议吗?然后您必须完全更改
for
循环。我想最好的办法是循环散列键:
对于我的$key(排序键%hash){…}
我正在尝试你建议的方法,唯一的问题是我无法将数据放入垃圾箱。如果我修改我的输入文件,你能帮我吗?对不起,我误解了你的问题。我已经修改了我的答案来解决这个问题…还有一个问题(如果我打扰了你,很抱歉!):有没有办法打印
,而不是用空格或制表符分隔的
标量键?(实际上,我不知道该在
say
命令中的何处添加此内容)无论如何,感谢您的耐心等待!