
次のファイルがあります。
gene.14977.0.1.p2 NbD023586.1.mrna1 100.0 132 0 0 1 132 1 132 4.9e-72 268.9
gene.14977.0.1.p2 NbD032405.1.mrna1 95.5 132 6 0 1 132 1 132 1.5e-68 257.3
gene.14983.1.1.p1 NbE05064429.1.mrna1 61.4 202 13 3 8 145 530 730 8.6e-51 198.7
gene.14983.1.1.p1 NbD024082.1.mrna1 59.3 209 13 3 8 145 530 737 5.6e-50 196.1
gene.14983.1.1.p1 NbD018021.1.mrna1 59.5 205 18 3 5 145 523 726 3.0e-48 190.3
gene.14986.0.0.p1 NbD007981.1.mrna1 100.0 422 0 0 9 430 1 422 1.8e-256 883.2
gene.14986.0.0.p1 NbD032402.1.mrna1 96.5 430 14 1 1 430 1 429 2.7e-252 869.4
gene.14986.0.0.p1 NbD023991.1.mrna1 85.3 428 61 1 1 428 1 426 2.1e-225 780.0
各遺伝子値(たとえば、最初の列)について、列11(たとえば)gene.14977.0.1.p2
の最小値を持つ行のみを維持したいと思います。4.9e-72
予想される出力は次のとおりです。
gene.14977.0.1.p2 NbD023586.1.mrna1 100.0 132 0 0 1 132 1 132 4.9e-72 268.9
gene.14983.1.1.p1 NbE05064429.1.mrna1 61.4 202 13 3 8 145 530 730 8.6e-51 198.7
gene.14986.0.0.p1 NbD007981.1.mrna1 100.0 422 0 0 9 430 1 422 1.8e-256 883.2
それはどのように可能ですか?
答え1
11番目の列から最小値を持つ行を抽出したい場合遺伝子別にグループ化次に、遺伝子識別子を連想配列のキーとして使用して、awk
その遺伝子の最小値を追跡する。
$ awk '{ gene = $1 } min[gene] == "" || min[gene] > $11 { min[gene] = $11; line[gene] = $0 } END { for (gene in line) print line[gene] }' file
gene.14983.1.1.p1 NbE05064429.1.mrna1 61.4 202 13 3 8 145 530 730 8.6e-51 198.7
gene.14977.0.1.p2 NbD023586.1.mrna1 100.0 132 0 0 1 132 1 132 4.9e-72 268.9
gene.14986.0.0.p1 NbD007981.1.mrna1 100.0 422 0 0 9 430 1 422 1.8e-256 883.2
ここでは、各遺伝子の最小値が現れる実際の行を追跡し、最後にその行を印刷します。
プログラムawk
の形式は次のとおりです。
{
# Pick out the gene name
gene = $1
}
min[gene] == "" || min[gene] > $11 {
# This gene hase either not been seen before,
# or its value in column 11 is smaller than
# what has been seen before (for this gene).
min[gene] = $11 # save small value from column 11
line[gene] = $0 # save whole line
}
END {
# Print all remembered lines.
for (gene in line)
print line[gene]
}
メンテナンスが難しいコードが好きな人のための最小化された1行バージョン:
awk 'm[$1]==""||m[$1]>$11{m[$1]=$11;t[$1]=$0}END{for(g in t)print t[g]}' file
sort
GNU(科学的表記法で数字を「人間の数字をソートする」)を使用して、同じ結果(おそらく異なる順序で)を得ることもできます。
$ sort -k1,1 -k11,11g file | sort -u -k1,1
gene.14977.0.1.p2 NbD023586.1.mrna1 100.0 132 0 0 1 132 1 132 4.9e-72 268.9
gene.14983.1.1.p1 NbE05064429.1.mrna1 61.4 202 13 3 8 145 530 730 8.6e-51 198.7
gene.14986.0.0.p1 NbD007981.1.mrna1 100.0 422 0 0 9 430 1 422 1.8e-256 883.2
ここで、最初のソートは、行が遺伝子(最初の列)でソートされ、各遺伝子の行が列11に基づいて数値でソートされるようにデータをソートします。次に、2番目はsort
各遺伝子の行を選択します(-u
このオプションのおかげで、各ソートキーに対して単一の項目を要求します)。この単一行は各遺伝子の最初の行になり、列11で最も小さい値を持つ行になります(最初の行によるsort
)。
sort
2番目のプログラムの代わりに短いプログラムを使用できますawk
。これは大量のデータに対して少し高速です。
sort -k1,1 -k11,11g file | awk '!seen[$1]++'