0

allinfo.txt と chr1.txt の 2 つのファイルがあります。

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

2 つのファイルは非常によく似ていますが、実際には保持する情報の点で大きく異なります。ただし、非常に基本的に、私がやりたいことは次のとおりです。allinfo の各行について、4 番目の列の文字を取得し、chr1 の対応する行でその文字を検索し、表示される回数を数えます。2 回出てきたら、allinfo のその行に 1 0 0 (3 列) を追加します。1 回だけ表示される場合は、allinfo のその行に 0 1 0 (これも 3 列) を追加します。表示されない場合は、allinfo のその行に 0 0 1 を追加します。実際にこれを行うことができれば、次のものが得られるはずです。

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

最初に、最初の 5 列は allinfo.txt ファイルにすでにあったものであることに注意してください。chr1 は最初の行に 2 つの A があるので、最初の行に 1 0 0 を付けたに違いありません。2行目を見ると、chr1には2行目にGが1つしかないので、2行目に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 の特定の行を見て、その対立遺伝子が出現する回数を数えます。その数に応じて、必要な 3 つの列のどこに 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を丸呑みするのが理にかなっています。このような場合、出力を出力する代わりに、配列内の3つの数値を記憶し、ifs / elsesに適切に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";
    }
}
于 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 に答える