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:元の列1
file1
- ファイル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