【问题标题】:Perl - Counting variables in each line of a filePerl - 计算文件每一行中的变量
【发布时间】:2012-12-04 11:35:32
【问题描述】:

我有两个文件:allinfo.txt 和 chr1.txt。

allinfo.txt 看起来像

rs4477212    1   82154       A   A
rs3094315    1   752566      G   A 
rs3131972    1   752721      A   G 
rs12124819   1   776546      A   G  

虽然 chr1.txt 看起来像

rs4477212    1   82154       A  A
rs3094315    1   752566      A  G
rs3131972    1   752721      A  G
rs12124819   1   776546      A  A

虽然这两个文件看起来很相似,但它们所携带的信息实际上却大不相同。但是,基本上,我想要做的是:对于 allinfo 中的每一行,我想获取第四列中的字母并在 chr1 中的相应行中搜索该字母并计算它出现的次数。如果它出现两次,我想将 1 0 0(三列)附加到该行的 allinfo。如果它只出现一次,我想将 0 1 0(同样是三列)附加到 allinfo 的那一行。如果它没有出现,我想将 0 0 1 附加到 allinfo 的那一行。如果我真的能做到这一点,我应该得到以下结果:

rs4477212    1   82154       A   A  1 0 0
rs3094315    1   752566      G   A  0 1 0
rs3131972    1   752721      A   G  0 1 0
rs12124819   1   776546      A   G  1 0 0

首先请注意,前五列正是 allinfo.txt 文件中已有的内容。由于 chr1 在第一行有两个 A,所以我必须将 1 0 0 附加到第一行。看第二行,由于 chr1 在第二行只有一个 G,那么我必须在第二行附加 0 1 0 。其余类似。

到目前为止我的代码:

#!/usr/bin/perl

use strict;
use warnings;

use File::Slurp;

use Data::Dumper;

open(FILE, '<', 'test_chr1_allinfo.txt');

my @array = read_file('test_chr1.txt');

my %hash;
while (<FILE>)
{
    (my $rs, my $chr, my $bp, my $a0, my $a1) = split(" ");
    my $line = $.;
    my $allele = $a0;
    $hash{$line} = $allele;
}   


foreach my $item (keys %hash)
{
...
}

如您所知,我不确定我将如何进行 foreach 循环。我通过将键作为该行中第一个等位基因的行号并将其分配给该行中列出的第一个等位基因来构建我的哈希。然后,我将遍历我的哈希,对于每个项目,查看 chr1 中的特定行并计算等位基因出现的次数。根据这个数字,我可以找出在我需要的三列中放置 1 的位置。但是,我不知道如何编写代码,因为我刚开始为这个项目学习 Perl。有人有什么想法吗?

我遇到的另一个问题是:当我打印我的哈希以便查看其中的内容时,为什么它会乱七八糟?根据我的构建方式,我希望它看起来像

1 => A
2 => G
3 => A
4 => A

但是,我得到了类似的东西

4 => A
2 => G
3 => A
1 => A

为什么会这样?

提前感谢您的任何建议/建议/帮助!

【问题讨论】:

  • 不保证哈希的顺序。哈希的顺序不必与创建它的顺序相同。
  • 有趣。有什么理由会这样吗?
  • 与存储在连续位置的数组不同,哈希分散在内存中。
  • @Peter:它使查找速度更快。
  • @Peter:文件是否逐行对应?

标签: perl variables hash count


【解决方案1】:

此代码符合您的要求。请注意,仅使用最后一列,因为其余列对于任务并不重要。如果您实际上有更多的 chr* 文件要处理,那么使用 allinfo.txt 是有意义的。在这种情况下,您不必打印输出,而是必须记住数组中的三个数字并在 ifs/else 中适当地加 1(例如 @counts[$.][0]++)。

#!/usr/bin/perl
use warnings;
use strict;

open my $ALL, '<', 'allinfo.txt' or die $!;
open my $CHR, '<', 'chr1.txt'    or die $!;

while (<$ALL>) {
    chomp;
    my @alleles_all = (split)[-2, -1];
    chomp(my $chr = <$CHR>); # Reads both files line by simultaneously.
    my @alleles_chr = (split ' ', $chr)[-2, -1];
    if ($alleles_chr[0] eq $alleles_chr[1]) {
        if ($alleles_chr[0] eq $alleles_all[0]) {
            print "$_\t1\t0\t0\n";
        } else {
            print "$_\t0\t0\t1\n";
        }
    } else {
        print "$_\t0\t1\t0\n";
    }
}

【讨论】:

  • 谢谢!伙计,这对我来说完全有道理……但为什么我不能自己做……
【解决方案2】:

这样就可以了

use strict;
use warnings;

open my $all, '<', 'allinfo.txt' or die $!;
open my $chr1, '<', 'chr1.txt' or die $!;

while (my $line = <$all>) {

  chomp $line;
  my $f4 = (split ' ', $line)[3];

  my $line2 = <$chr1>;
  my $n = grep $_ eq $f4, (split ' ', $line2)[3, 4];

  my @newline = ($line, 0, 0, 0);
  $newline[-($n+1)] = 1;
  print "@newline\n";
}

输出

rs4477212    1   82154       A   A  1 0 0
rs3094315    1   752566      G   A  0 1 0
rs3131972    1   752721      A   G  0 1 0
rs12124819   1   776546      A   G  1 0 0

【讨论】:

    【解决方案3】:

    这是另一个选择:

    use Modern::Perl;
    use File::Slurp qw/read_file/;
    
    my %patterns = ( 0 => "0\t0\t1", 1 => "0\t1\t0", 2 => "1\t0\t0" );
    
    chomp( my @allinfo = read_file 'allinfo.txt' );
    my @chr1 = read_file 'chr1.txt';
    
    for my $i ( 0 .. $#allinfo ) {
        my $allinfoCol3 = ( split ' ', $allinfo[$i] )[3];
        my ($chr1Cols) = $chr1[$i] =~ /(\S+\s+\S+)$/;
        my $count = () = $chr1Cols =~ /$allinfoCol3/g;
        say "$allinfo[$i]\t$patterns{$count}";
    }
    

    输出:

    rs4477212    1   82154       A   A  1   0   0
    rs3094315    1   752566      G   A  0   1   0
    rs3131972    1   752721      A   G  0   1   0
    rs12124819   1   776546      A   G  1   0   0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      • 2023-03-17
      相关资源
      最近更新 更多