以下の例のようなファイルがあります。最初の列はSNP IDです。
head data
2L:647803 1 2 44.31655 -12.2373
2L:647803 1 2 43.63717 -12.302
2L:647803 1 2 43.80007 -12.3451
2L:2602906 1 2 43.39748 -11.4894
2L:2602906 1 2 44.43951 -12.3093
2L:2602906 1 2 43.80007 -12.3451
2L:3146785 1 2 44.31655 -12.2373
2L:3146785 1 2 44.43951 -12.3093
2L:3146785 1 2 43.80007 -12.3451
2L:3771395 1 2 43.39748 -11.4894
2L:3771395 1 2 43.2661 -11.6803
2L:3945568 1 2 43.63717 -12.302
2L:3945568 1 2 43.39032 -11.6099
各SNP(2L:647803
、、、、...)に対して3つの行が必要です2L:2602906
。2L:3146785
各SNPに3行がない場合は、そのSNPを削除したいと思います。これが私が望む出力です。 (各出力のインスタンスは2つしかないので削除されました。2L:3771395
) 2L:3945568
head desired
2L:647803 1 2 44.31655 -12.2373
2L:647803 1 2 43.63717 -12.302
2L:647803 1 2 43.80007 -12.3451
2L:2602906 1 2 43.39748 -11.4894
2L:2602906 1 2 44.43951 -12.3093
2L:2602906 1 2 43.80007 -12.3451
2L:3146785 1 2 44.31655 -12.2373
2L:3146785 1 2 44.43951 -12.3093
2L:3146785 1 2 43.80007 -12.3451
答え1
エレガントではありませんが、実用的です。
$ awk 'NR==FNR {a[$1]++; next} a[$1]==3' data data
2L:647803 1 2 44.31655 -12.2373
2L:647803 1 2 43.63717 -12.302
2L:647803 1 2 43.80007 -12.3451
2L:2602906 1 2 43.39748 -11.4894
2L:2602906 1 2 44.43951 -12.3093
2L:2602906 1 2 43.80007 -12.3451
2L:3146785 1 2 44.31655 -12.2373
2L:3146785 1 2 44.43951 -12.3093
2L:3146785 1 2 43.80007 -12.3451
答え2
ミラーの使用(https://github.com/johnkerl/miller)と実行
mlr --nidx count-similar -g 1 then filter '$count==3' then cut -x -f count inputfile
あなたは
2L:647803 1 2 44.31655 -12.2373
2L:647803 1 2 43.63717 -12.302
2L:647803 1 2 43.80007 -12.3451
2L:2602906 1 2 43.39748 -11.4894
2L:2602906 1 2 44.43951 -12.3093
2L:2602906 1 2 43.80007 -12.3451
2L:3146785 1 2 44.31655 -12.2373
2L:3146785 1 2 44.43951 -12.3093
2L:3146785 1 2 43.80007 -12.3451
mlr --nidx count-similar -g 1
さまざまなフィールドの値の計算 1then filter '$count==3'
この数が3の行のみをフィルタリングします。then cut -x -f count
数列の削除
答え3
ここに別のawk
(ちょうどawk
)解決策があります。
- 入力が「SNP id」でソートされていると仮定します。つまり、SNP id = 647のすべての行が一緒になります。
- 入力が注文されたとは仮定しません。つまり、SNP ID 647 が 2602 の前または後に表示されることがあります。
- データは一度だけ渡されます。
- 3回以上表示されるSNP IDのデータは出力されません。
awk '
{
if ($1 == last) {
count++
if (count <= 3) line[count] = $0
} else {
if (count == 3) { print line[1]; print line[2]; print line[3]; }
last = $1
count = 1
line[count] = $0
}
}
END { if (count == 3) { print line[1]; print line[2]; print line[3]; } }
'
最初のフィールド/列()で同じ値を持つ連続行を計算し、$1
同じ値を持つ行を保存します。新しい値(または入力の終わり)が見つかると、古い値が3回発生したときに保存された行が印刷されます。