awkを使用して1つのフィールドがしきい値より小さいCSVファイルの行のみを選択する

awkを使用して1つのフィールドがしきい値より小さいCSVファイルの行のみを選択する

多くの(10000+)行を含む複数列のcsvファイルの後処理:

ID(Prot), ID(lig), ID(cluster), dG(rescored), dG(before), POP(before)
9000, lig662, 1, 0.421573, -7.8400, 153
10V2, lig807, 1, 0.42692, -8.0300, 149
3000, lig158, 1, 0.427342, -8.1900, 147
3001, lig158, 1, 0.427342, -8.1900, 147
10V2, lig342, 1, 0.432943, -9.4200, 137
10V1, lig807, 1, 0.434338, -8.0300, 147
4000, lig236, 1, 0.440377, -7.3200, 156
10V1, lig342, 1, 0.441205, -9.4200, 135
4000, lig497, 1, 0.442088, -7.7900, 148
9000, lig28, 1, 0.442239, -7.5200, 152
3001, lig296, 1, 0.444512, -7.8900, 146
10V2, lig166, 1, 0.447681, -7.1500, 157
....
4000, lig612, 1, 0.452904, -7.0200, 158
9000, lig123, 1, 0.461601, -6.8000, 160
10V1, lig166, 1, 0.463963, -7.1500, 152
10V1, lig369, 1, 0.465029, -7.3600, 148

今まで何をしたのか

awkbashCSVから1%(一番上の行)を取得し、新しいCSV(したがって減少した行数を含む)として保存する関数に組み込まれている次のコードを使用しています。

take_top44 () {
    # Take the top lines from the initial CSV
    awk -v lines="$(wc -l < original.csv)" '
    BEGIN{
      top=int(lines/100)
    }
    FNR>(top){exit}
    1
    ' original.csv >> csv_with_top_lines.csv
}

私が今やりたいこと

awk元のCSVにより選択的なフィルタを適用するには、コードをどのように変更する必要がありますか?たとえば、4番目の列(in)の値(浮動小数点数)に基づいてデータをフィルタリングしますdG(rescored)

minForth = 0.421573たとえば、最も低い値(常に2行目)を参照として使用し、選択したしきい値(たとえば20%を超える)$4より小さいCSVのすべての行を印刷する必要があります。minForth

$4<=(1+0.2)*min))'

ベストアンサー1

4番目のフィールドがしきい値未満のすべての行のみをフィルタリングするには、awk次のコマンドを使用できます。

awk -F',' -v margin=0.2 'FNR==2 {min=$4} FNR>1&&($4<=(1+margin)*min)' input.csv

または、フィルタリングされた出力にヘッダーを含めたい場合:

awk -F',' -v margin=0.2 'FNR==2 {min=$4} FNR==1||($4<=(1+margin)*min)' input.csv

これにより、フィールド区切り文字がに設定されます,(ただし、フィールドを区切る余分なスペースがあるため、ファイルは非標準CSVであることに注意してください)、margin値を持つ変数をプログラム0.2にインポートします。awk

プログラム内でmin2行()にある場合は、FNR==2変数の値を4列の値に設定します。行1(ヘッダー - 必要な場合)にある場合、またはファイルのデータセクションにあり、4番目のフィールドが1+margin最小値の倍数より小さい場合は、現在の行のみを印刷します。

おすすめ記事