段階的に

段階的に

2つのファイルがあります。ファイル1の列1はファイル2の列2に置き換える必要があり、ファイル1の列2,3,4-5または5-4(クロスマッチ)は列1,4,5と一致します。 -6またはファイル2の6-5。

ファイル1

SNP     Chr     Pos     EA      NEA     EAF     Beta    SE      Pvalue  Neff
1:79137     1       79137       A       T       0.25    -0.026  0.0073  4.0e-04 231420
1:79033      1       79033        A       G       0.0047  -0.038  0.056   4.9e-01 225429
1:118630     1       118630       C       T       0.99    -0.033  0.055   5.5e-01 226311
1:533179     1       533179       A       G       1       -0.098  0.19    6.1e-01 185906

ファイル2

1       1:79033_A_G     0       79033   A       G
1       1:79137_A_T     0       79137   T       A
1       1:118630_C_T    0       118630  T       C
1       1:533179_A_G    0       533179  G       A

次の出力が必要です。

SNP     Chr     Pos     EA      NEA     EAF     Beta    SE      Pvalue  Neff
    1:79137_A_T     1       79137       A       T       0.25    -0.026  0.0073  4.0e-04 231420
    1:79033_A_G      1       79033        A       G       0.0047  -0.038  0.056   4.9e-01 225429
    1:118630_C_T     1       118630       C       T       0.99    -0.033  0.055   5.5e-01 226311
    1:533179_A_G     1       533179       A       G       1       -0.098  0.19    6.1e-01 185906

ファイルに正確な行がないため、ファイルはタブで区切られません。以下のコードを試しましたが、うまくいきません。コードを修正してもらえますか?

awk 'NR==FNR{chr[$1]=$1;snp[$2]=$2;pos[$4]=$4;a1[$5]=$5;a2[$6]=$6;next} ($1 in chr)&&($4 in pos)&& ((($5 in a1) && ($6 in a2)) || (($6 in a1) && ($5 in a2))) {$2==snp[$2]}' file 2 file1

編集1:

次のPerlコードはいくつかのエラーを引き起こし、約20,000の重複行を生成します。

ファイル1

SNP     Chr     Pos     EA      NEA     EAF     Beta    SE      Pvalue  Neff
7:10100610      7       10100610        A       G       0.0002  0.13    0.58    8.2e-01 120658
7:10100610      7       10100610        C       G       0.0013  0.1     0.13    4.4e-01 139170
10:1006107      10      1006107 C       G       1       -0.11   0.42    7.9e-01 152016

ファイル2

7       7:10100610_G_A  0       10100610        A       G
7       7:10100610_G_C  0       10100610        C       G
10      10:1006107_C_G  0       1006107 G       C

次の行の推定出力は次のとおりです。

7:10100610_G_A      7       10100610        A       G       0.0002  0.13    0.58    8.2e-01 120658
7:10100610_G_C      7       10100610        C       G       0.0013  0.1     0.13    4.4e-01 139170
10:1006107_C_G      10      1006107 C       G       1       -0.11   0.42    7.9e-01 152016

しかし、Perlコードは出力を提供します。

7:10100610_G_A  7       10100610        A       G       0.0002  0.13    0.58    8.2e-01 120658
10:1006107_C_G  7       10100610        C       G       0.0013  0.1     0.13    4.4e-01 139170
10:1006107_C_G  10      1006107 C       G       1       -0.11   0.42    7.9e-01 152016

答え1

このjoinコマンドは、複数のファイルで一致する行をリンクする操作を実行します。ただし、入力ファイルにはいくつかの要件があるため、プロセス中にいくつかの一時ファイルといくつかの追加フィールドを作成する必要があります。

awk '{printf $2" "$3" "$4" "$5"%"$1"%"; $1="";print $0 "%" NR }' < file1 | sort > 1.tmp
awk '{print $1" "$4" "$5" "$6"%"$2} $5 != $6 {print $1" "$4" "$6" "$5"%"$2}' < file2 | sort > 2.tmp

join -a 1 -t % -o 1.4 2.2 1.2 1.3  1.tmp 2.tmp | sort -t % -n | awk -F %  '!$2{$2=$3}{print $2" "$4}'

段階的に

最初のファイルを前処理します。

awk '{printf $2" "$3" "$4" "$5"%"$1"%"; $1="";print $0 "%" NR }''

出力例:

1 118630 C T%1:118630% 1 118630 C T 0.99 -0.033 0.055 5.5e-01 226311%4

この 4 つのフィールドは%次のように区別されます。

  • 一致する必要がある「キー」(入力フィールド2-5)
  • 元の最初の列(一致する項目がない場合は必須)
  • 元の行の残りの部分
  • 元の行番号(後でファイルの順序を復元できるようにsort

この出力は入力をソートする必要があるため、一時ファイルsortにパイプされます。join

2番目のファイルの場合:

awk '{print $1" "$4" "$5" "$6"%"$2} $5 != $6 {print $1" "$4" "$6" "$5"%"$2}'

出力例:

1 118630 C T%1:118630_C_T
1 118630 T C%1:118630_C_T

フィールド5と6が一致するように指定すると、2行目が印刷され、互いに置き換えられます(同じでない場合)。ここで - で区切られたフィールド%は次のとおりです。

  • 「キー」と一致する必要があります
  • 2列

今回も出力はsort別の一時ファイルにパイプされます。

その後、主な「参加」ステップが続きます。

join -a 1 -t % -o 1.4 2.2 1.2 1.3  1.tmp 2.tmp

2番目のグループに一致するものがない場合は、 -a 1最初のグループの行を保持するように指示します。区切り文字を(スペースの代わりに)に設定します。このパラメーターは、次の4つの出力フィールドを生成します。join-t %%-o

  • ファイル1、列4:行番号
  • ファイル2、列2:代替場所file2(一致するものがない場合は空)
  • ファイル1、列2:元の列1file1
  • ファイル1、列3:行の残りの部分はfile1

サンプル出力ライン:

4%1:118630_C_T%1:118630% 1 118630 C T 0.99 -0.033 0.055 5.5e-01 226311

その後、sort元のファイルの順序を復元できます(数値ソート、フィールド区切り文字%)。

sort -t % -n

最後に、awk「交換」フィールドが空であることを確認し(一致する項目がないため)、空の場合は元の列1を使用します。また、行番号とすべてを捨てます%

awk -F % '!$2{$2=$3}{print $2" "$4}'

最終出力ライン:

1:118630_C_T  1 118630 C T 0.99 -0.033 0.055 5.5e-01 226311

答え2

私はPerlでこれをします。 Perlには、andを同じものとしてsort簡単に処理できる機能があるからです。たとえば、すべてのサンプルファイルの出力を組み合わせて表示します。A TT A

$ perl -lane 'if(!$k){$name{join("","chr".$F[0],$F[3],sort($F[4],$F[5]))}=$F[1]; }else{$var=join("", "chr".$F[1],$F[2],sort($F[3],$F[4])); $F[0]=$name{$var} if $name{$var};print join "\t", @F; } $k++ if eof' file2 file1
SNP Chr Pos EA  NEA EAF Beta    SE  Pvalue  Neff
7:10100610_G_A  7   10100610    A   G   0.0002  0.13    0.58    8.2e-01 120658
7:10100610_G_C  7   10100610    C   G   0.0013  0.1 0.13    4.4e-01 139170
10:1006107_C_G  10  1006107 C   G   1   -0.11   0.42    7.9e-01 152016
1:79137_A_T 1   79137   A   T   0.25    -0.026  0.0073  4.0e-04 231420
1:79033_A_G 1   79033   A   G   0.0047  -0.038  0.056   4.9e-01 225429
1:118630_C_T    1   118630  C   T   0.99    -0.033  0.055   5.5e-01 226311
1:533179_A_G    1   533179  A   G   1   -0.098  0.19    6.1e-01 185906

または少し明確です。

$ perl -lane 'if(!$k){
                $name{join("","chr".$F[0],$F[3],sort($F[4],$F[5]))}=$F[1]; 
              }
              else{
                $var=join("", "chr".$F[1],$F[2],sort($F[3],$F[4])); 
                $F[0]=$name{$var} if $name{$var};
                print join "\t", @F; 
             } 
            $k++ if eof' file2 file1
SNP Chr Pos EA  NEA EAF Beta    SE  Pvalue  Neff
7:10100610_G_A  7   10100610    A   G   0.0002  0.13    0.58    8.2e-01 120658
7:10100610_G_C  7   10100610    C   G   0.0013  0.1 0.13    4.4e-01 139170
10:1006107_C_G  10  1006107 C   G   1   -0.11   0.42    7.9e-01 152016
1:79137_A_T 1   79137   A   T   0.25    -0.026  0.0073  4.0e-04 231420
1:79033_A_G 1   79033   A   G   0.0047  -0.038  0.056   4.9e-01 225429

説明する

  • perl -lane:これは-aPerlをawkのように動作させ、自動的に入力を空白の配列に分割します@F。 Perl配列は最初のフィールドで始まる0ので、2番目のフィールドになります。フィールドNはです。 Perlは引数をテキストファイルとして読み込み、与えられたスクリプトを各行に適用します。各行から末尾の改行を削除し、各呼び出しに改行を追加するだけです。$F[0]$F[1]$F[N-1]-n-e-lprint

  • $k++ if eof$k:ファイルの終わり(eof)に達すると、変数は1増加します。その後、if(!$k)($ kが定義されていない場合)、NR==FNRawkで同等のものとして使用できます。

  • if(!$k){$name{join("","chr".$F[0],$F[3],sort($F[4],$F[5]))}=$F [1];} : if this is the first file,file2 , join fields 1, 4, and the sorted fields 5 and 6, into a string and use that string as the key in the hash (associative array)name . Then, save the variant's name from file2 as the value associated with that key. The sorting lets us treatAT andTA 「as equivalent. I usechr to deal with cases likeand

  • else{:今2番目のファイルを読んでいる場合file1

  • $var=join("", $F[1],$F[2],sort($F[3],$F[4]));:ビルドキー。今回は、フィールド2、3を使用して4と5を並べ替えます。
  • $F[0]=$name{$var} if $name{$var};name:キーに値がある場合、最初のフィールドをハッシュに格納された値に設定します。ヘッダーや存在するが存在しない他のバリアントをif変更しないでください。file1file2
  • print join "\t", @F;:上記で行った変更を含むフィールドを印刷します。

関連情報