Awk - 列の値を変数と比較して、各IDが渡された回数を計算します。

Awk - 列の値を変数と比較して、各IDが渡された回数を計算します。

解決策を見つけようとしましたが、今は助けが必要です。

まず、入力として次の構造の大容量ファイル(5.5G)があります。

scaffold4691_size302    2       T       1
scaffold4691_size302    3       A       1
scaffold4691_size302    4       a       1
scaffold4691_size302    5       a       1
scaffold4691_size302    6       g       2
scaffold4691_size302    7       c       2
scaffold4691_size302    8       c       2
scaffold4692_size187    68      g       4
scaffold4692_size187    69      c       4
scaffold4692_size187    70      a       4
scaffold4692_size187    71      a       4

私が望むのは、最初の列($ 1)の各IDについて、4番目の列($ 4)の値がX以上の回数(たとえば、おもちゃモデルのX = 4)を計算することです。

だから私は入力として次のことを楽しみにしています。

scaffold4691_size302    0
scaffold4691_size187    4

Pythonはより快適で簡単にできましたが、サイズが大きすぎます。

これまで私はこれをしました:

awk 'NR>1 { scf=$1; { if ($4>=4){count++;}}} {print scf "\t" count}' toyModel

しかし、すべての行と合計が返されます。新しいIDの数を更新する方法を知りたいです。

答え1

各IDの数を累積し、ファイルを処理した後に結果を印刷する必要があります。

awk '!counts[$1] { counts[$1] = 0 }; $4 >= 4 { counts[$1]++ }; END { for (key in counts) print key, counts[key] }' toyModel

最初のステートメントは、私たちが測定するIDが基準と絶対に一致しないことを保証します(最終出力は0です)。 2番目は一致する行数を増やします。最後のステートメントはキー(ID)を繰り返し、キーと一致する数を印刷します。

このメソッドのサイズが大きすぎ(配列が大きすぎるcounts)IDがファイル内で連続している場合は、代わりにこのメソッドを使用できます。

awk 'curid != $1 { if (NR > 1) print curid, count; curid = $1; count = 0 }; $4 >= 4 { count++ }; END { print curid, count }' toyModel

これは現在のIDと数を保持し、IDが変更されたとき(最後に)それを印刷します。 4番目のフィールドが4より大きいたびに数が増え、IDが変更されるたびにリセットされます。

答え2

perl -lane '$h{$F[0]} += $F[3] >= 4 ? 1 : 0}{print "$_\t$h{$_}" for keys %h' toyModel

関連情報