私はかなりユニークな問題で立ち往生しています。私が読んでいる2つのファイルがあります。これら 2 つのファイルの小さいバージョンは、次のようになります。
ファイル1
chr1 9873 12227 11873 2354 + NR_046018 DDX11L1
chr1 760970 763155 762970 2185 + NR_047520 LOC643837
ファイル2
chr1 9871 0
chr1 9872 1
chr1 9873 1
chr1 9874 2
chr1 9875 1
chr1 9876 3
chr1 9877 3
chr1 760970 1
chr1 760971 1
chr1 760972 1
chr1 760973 2
chr1 760974 3
chr1 760975 3
chr1 760976 4
chr1 760977 5
chr1 760978 6
chr1 760979 7
chr1 760980 6
chr1 760981 7
chr1 760982 8
chr1 760983 9
chr1 760984 10
chr1 760985 11
chr1 760986 12
chr1 760987 10
chr1 760988 9
chr1 760989 6
問題
最初のファイルから、各行から 2 番目の要素を取得し、それを
$start
. 終了位置は によって決定され$end = $start + 10
ます。に基づいて
$start
、2 番目のファイルを取得し、各行の 2 番目の要素を確認する必要があります。が見つかったら$start
、3 番目の要素の次の 5 つの対応する値を 5 個ずつ合計する必要があります$end
。
そのまま$end
で$start + 10
、5 つのグループで合計すると、2 つの合計値が得られます。
$end
2 番目のファイルの 2 番目の要素に最大の値が存在しない場合、コードは停止せず、合計を実行し続け、合計を 0 として表示する必要があります (連続する 5 つの要素のグループが存在しない場合)。
ここでファイルの例を挙げると、File19873
から、に割り当てられている2 番目の要素 = $start
。したがって$end
、$start+10
つまり 9883 になります。
File2から、行の 2 番目の要素で1 回$start
検出され、次の 5 行の 3 番目の要素を 1 つのグループとして合計し、次の 5 つの値を 2 番目のグループとして合計する必要があります$end
。
ノート
ここでFile2に見られるように、$end
つまり 9883 は存在しません。したがって、9879 から 9883 までの値の合計は でなければなりませんzero
。760970 以降の値を合計してはなりません...
望ましい出力
chr1 9873 12227 11873 2354 + NR_046018 DDX11L1 10 0
chr1 760970 763155 762970 2185 + NR_047520 LOC643837 8 25
注意事項
- 実際のファイルを扱っている間、 $end = $start+10,000( $end = $start+10 の代わりに)
- また、同じメモで、25 の値のグループが ( 5 ではなく) 合計され、実際のファイルの操作中に合計 400 の値が取得されます。
- $file2 の 2 番目の要素に存在しない値の範囲がある場合、25 個の値の連続したペアが存在しない場合は、合計が通常どおり続行され、
0
出力されます。 - ファイルには、それぞれ 100 万行を超える行が含まれています。
コード
これまでに書いたコードは、次のことを管理しています。
- ファイルから読み取ります。
- 割り当て
$start
て$end
、file1から - file2から、すべての 2 番目の要素を array にプッシュし
@c_posn
ます。すべての 3 番目の要素を array に@peak
。 $start
が存在するかどうかを確認します@c_posn
合計部分の実行方法がわかりません。2番目のファイルのすべての2番目の要素がキーになり、3番目の要素が値になるハッシュを作成することを考えていました。しかし、ハッシュは順不同です。そこで、2 番目の要素と 3 番目の要素の 2 つ@c_posn
の配列を作成しました@peaks
。しかし、今では2つの配列を同時に比較する方法がわかりません(760970の値が合計されないようにするため)
use 5.012;
use warnings;
use List::Util qw/first/;
my $file1 = 'chr1trialS.out';
my $file2 = 'b1.wig';
open my $fh1,'<',$file1 or die qw /Can't_open_file_$file1/;
open my $fh2,'<',$file2 or die qw /Can't_open_file_$file2/;
my($start, $end);
while(<$fh1>){
my @val1 = split;
$start = $val1[1]; #Assign start value
$end = $start + 10; #Assign end value
say $start,"->",$end; #Can be commented out
}
my @c_posn;
my @peak;
while(<$fh2>){
my @val2 = split;
push @c_posn,$val2[1]; #Push all 2nd elements
push @peak, $val2[2]; #Push all 3rd elements
}
if (first { $_ eq $start} @c_posn) { say "I found it! " } #To check if $start is present in @c_posn
say "@c_posn"; #just to check all 2nd elements are obtained
say "@peak"; #just to check all 3rd elements are obtained
私の問題を解決するために時間を割いていただきありがとうございます。説明が必要な場合は、私に尋ねてください。すべてのコメント/回答に感謝します。