データファイルがありますA.tsv
(フィールド区切り記号= \t
)。
id clade mutation
243 40A siti,toto,mumu
254
267 40B lala,sisi,sojo
とテンプレートファイルB.tsv
(フィールド区切り記号= \t
):
40A toto,xixi,saxa
40B lala,sojo,huhu
40C sasa,sisi,lala
共通のcladeに基づいてA.tsv
テンプレートの突然変異を比較したいと思いますB.tsv
。 2つの質問があります。
B.tsv
「missing_mutation」という新しい列に存在しない突然変異の名前をどのように表示できますかA.tsv
?A.tsv
に存在するが(文字で始まりs
、大文字と小文字を区別しない)には、存在しない突然変異の名前を "remaining_mutation"という新しい列にどのように表示できますかB.tsv
?
C.tsv
次のようになります。
id clade mutation missing_mutation remaining_mutation
243 40A siti,toto,mumu xixi,saxa siti
254
267 40B lala,sisi,sojo huhu sisi
次のように2つのファイルを比較する方法を知っています。
awk -F"," -vOFS="," '
NR==FNR {
a[$2]=$3;
next
}
{ print $0,a[$2] }
' B.tsv A.tsv > C.tsv
しかし、一致しないアイテムを印刷する方法がわかりません。良いアイデアがありますか?
ベストアンサー1
次のawk
プログラムは、便宜上awk
(「真の二重インデックス配列」の形で)GNUを使用しており、この問題を解決する必要があります。これは、2つのファイルを引数として使用して順番に呼び出すことを目的としていますB.txt
A.txt
(コード例で行ったのと同じように)。
#!/bin/awk -f
BEGIN{FS=OFS="\t"}
NR==FNR {
n_tmp[$1]=split($2,buff,/,/)
for (i=1;i<=n_tmp[$1];i++) mut_tmp[$1][i]=buff[i]
next
}
FNR==1 {
print $0,"missing_mutation","remaining_mutation"
}
FNR>1 {
n_curr=split($3,mutations,/,/)
mut_miss=0
mut_rem=0
# Find missing
for (j=1;j<=n_tmp[$2];j++)
{
for (i=1;i<=n_curr;i++)
{
if (mutations[i]==mut_tmp[$2][j]) break
}
if (i>n_curr) mut_miss=mut_miss ? mut_miss "," mut_tmp[$2][j] : mut_tmp[$2][j]
}
# Find remaining
for (i=1;i<=n_curr;i++)
{
for (j=1;j<=n_tmp[$2];j++)
{
if (mutations[i]==mut_tmp[$2][j]) break;
}
if (j>n_tmp[$2] && mutations[i]~/^[Ss]/) mut_rem=mut_rem ? mut_rem "," mutations[i] : mutations[i]
}
if (!mut_miss) mut_miss=""
if (!mut_rem) mut_rem=""
print $0,mut_miss,mut_rem
}
- これにより、最初にclade nrの相関テーブルが作成されます。テンプレートを解析するときは、それを突然変異リストと比較してください
B.tsv
。ここで、テンプレート突然変異リストは明示的に個々の突然変異配列に分割される。便宜上、mut_tmp
最初のインデックスが分岐番号の「デュアルインデックス」配列を使用していることに注意してください。 2番目は、突然変異のインデックス番号です。突然変異の数も配列に保存されますn_tmp
。 - 解析するときは、
A.tsv
新しいヘッダーを最初に印刷します。 - 次に、各行に対して最初にフィールド3のバリアントリストを配列に分割します
mutations
。 - 次に、現在のクレード()のテンプレート突然変異リスト内の各項目を既存の
mut_tmp[$2]
突然変異()とmutations
比較して、「欠落突然変異」フィールドを埋めます。 s
次に、現在のバリエーションリストの各項目を現在のクレードのテンプレートバリエーションと比較して、「残りのバリエーション」フィールドを埋め、バリエーションがまたはで始まることを確認しますS
。
GNUが利用できない場合は、次のものを置き換えて他awk
のほとんどの実装で動作させることができます。awk
mut_tmp[a][b]
そして
mut_tmp[a,b]
\034
これは、系統番号と突然変異名が基本的に個々のコンポーネントを単一の文字列配列インデックスに関連付けるために使用される特殊文字を含まないように見えるために機能します(SUBSEP
詳細は内部変数を参照してください)。
入力例の出力は次のとおりです。
~$ awk -f compare.awk B.tsv A.tsv
id clade mutation missing_mutation remaining_mutation
243 40A siti,toto,mumu xixi,saxa siti
254
267 40B lala,sisi,sojo huhu sisi
例で必要な出力が要件の説明と一致しません。
編集する
A.tsv
実際、四半期群は22列にあり、突然変異は41列にあることをあなたの意見で指摘したので変更してください。
split($3,mutations,/,/)
到着split($41,mutations,/,/)
- すべての
n_tmp[$2]
発生n_tmp[$22]
mut_tmp[$2][j]
(または[$2,j]
)からmut_tmp[$22][j]
(または[$22,j]
)までのすべての項目