0

我有两个文件: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

为什么会这样?

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

4

3 回答 3

2

此代码符合您的要求。请注意,仅使用最后一列,因为其余列对于任务并不重要。如果您实际上有更多的 chr* 文件要处理,那么使用 allinfo.txt 是有意义的。在这种情况下,您不必打印输出,而是必须记住数组中的三个数字并在 ifs/elses 中适当地加 1(例如 as @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";
    }
}
于 2012-12-04T11:58:00.007 回答
0

这会成功的

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
于 2012-12-04T13:00:20.917 回答
0

这是另一种选择:

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
于 2012-12-04T17:29:18.013 回答