最初の列に基づいて特定の数の観測値がある場合、行を維持する方法は?

最初の列に基づいて特定の数の観測値がある場合、行を維持する方法は?

以下の例のようなファイルがあります。最初の列は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:26029062L: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さまざまなフィールドの値の計算 1
  • then 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回発生したときに保存された行が印刷されます。

関連情報