私のスクリプトは次のようになっています。スカラーの古いリストを取り、対応する数値の新しいリストを作成します。古いリストは @oldMarkers として参照され、新しいリストは @newMarkers として参照されます。
サンプル入力は次のようになります。 chr1, chr2, IMP, chr3, IMP, IMP, IMP, chr4
サンプル出力は次のようになります。1, 2, 2.1, 3, 3.1, 3.2, 3.3, 4
スクリプトのポイントは、@oldMarkers のリストを読み取り、「chr」という文字を含む要素のインスタンスごとに整数が配列 @newMarkers にプッシュされるリストを出力することです。@oldMarkers の IMP のインスタンスごとに、10 進数が @newMarkers に追加されます。新しい 10 進数は、前の数値と同じ "基本整数" を持ちますが、それに .1 が追加されます。言い換えれば、「IMP」の複数の連続するインスタンスは、最後に読み取られた「chr」エントリと同じ整数を持ち、その最新の「chr」に対応する IMP の数をカウントする 10 進数の値が付加されていると想定されます。エントリ。
以下のスクリプトは、ほぼ 100% 機能します。次の場合でも、通常は機能しています。@oldMarkers のいくつかの場所には、IMP の多数のエントリがあります。行に 10 を超える IMP がある場合、コードは @newMarkers に値をプッシュして、そのエントリ ブロックのすべての「IMP」が同じ整数を持つようにすることになっています。 @oldMarkers の「chr」のインスタンスを読み取ります。その整数に 0.1 が加算されます。そして、小数の値が .9 になると、小数は .1 に「最初から」戻り、そこから IMP エントリのストレッチの終わりまで上昇します。
たとえば、@oldMarkers に 13 個の「IMP」のブロックがあり、次の場合:
chr1, chr2, IMP, IMP, IMP, IMP, IMP, IMP, IMP, IMP, IMP, IMP, IMP, IMP, IMP, chr2
@newMarkers は次のようになります。
1, 2, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 2.1, 2.2, 2.3, 2.4, 3
スクリプトの要約:
元のファイルには、2 つの要素の複数行が含まれています。最初の要素は重要ではないため、コードではスキップされます。各行の 2 番目の要素は、"chr4" や "IMP" などの ID です。ループはwhile
各行を読み取り、2 番目の要素を配列 @oldMarkers に追加します。
次に、この配列はエントリごとに読み取られます。スクリプトは最初に、@newMarkers のエントリが元の @oldMarker リストの「chr」または「IMP」に対応するかどうかを尋ねます。これは、最初if
のelse
セットで行われます。
次に、両方の条件について、エントリが「chr」または「IMP」エントリに対応する番号自体に由来するかどうかがさらに尋ねられます。これは、最初のそのようなセットに組み込まれたセットでif
行われます。else
次に、新しい要素が定義され、条件に応じて @newMarker にプッシュされます。
私が言ったように、これはほとんどうまくいきます。ただし、IMP が 10 を超えて伸びると、スクリプトは小数を「リサイクル」しません。むしろ、前の値に .1 を追加し、新しい整数を入力します。しかし、10 を超える他のストレッチでは、問題なく機能します。この「エラー」とは矛盾します。
問題を見つけることができますか?
my @oldMarkers = ();
my @newMarkers = ();
while ( my $line = <$FILE> )
{
chomp $line;
my @entries = split( '\t', $line );
push( @oldMarkers, $entries[ 1 ] );
} ### end of while
for ( my $i = 0 ; $i < scalar @oldMarkers ; $i++ )
{
if ( $oldMarkers[ $i ] =~ m/chr/ ) ### is a marker
{
if ( $oldMarkers[ $i - 1 ] =~ m/IMP/ ) ### new marker comes after imputed site
{
push( @newMarkers, int( $newMarkers[ $i - 1 ] ) + 1 );
}
else ### is coming after a marker
{
push( @newMarkers, $newMarkers[ $i - 1 ] + 1 );
}
} ### if
else ### is an imputed site
{
if ( $oldMarkers[ $i - 1 ] =~ m/IMP/ ) ### imputed site is after another imputed site
{
my $value = $newMarkers[ $i - 1 ] - int( $newMarkers[ $i - 1 ] );
if ( $value < .9 )
{
push( @newMarkers, $newMarkers[ $i - 1 ] + .1 );
}
elsif ( $value > .9 )
{
push( @newMarkers, int( $newMarkers[ $i - 1 ] ) + .1 );
}
} ### if
else ### imputed site is after a marker
{
push( @newMarkers, int( $newMarkers[ $i - 1 ] ) + .1 );
}
} ### else
} ### for
print $newMarkerfile join( "\t", @newMarkers);