我有以下数据框示例。您可以看到第三列的元素可以重复。我想保留第 5 列中具有最高值的条目
意思是对于AGCCCGGGG我想保留第二个条目,第五列的值为 49。
A00643:620:HFM7YDSX5:1:1124:7120:12352 ATCAGCCCGGGGCTTGGGCTAGGAC GGGTGTGTG 548476 0 Corynebacterium
A00643:620:HFM7YDSX5:1:1150:15953:12524 CCTATCGTCGCTGGAATTCCCCGGG AGCCCGGGG 1458266 1 Bordetella
A00643:620:HFM7YDSX5:1:1150:15628:12743 CCTATCGTCGCTGGAATTCCCCGGG AGCCCGGGG 1458266 49 Bordetella
A00643:620:HFM7YDSX5:1:1450:4001:4507 GGCGATCGAAATGTCAAGCCCGGGG TCTTGTGGT 585529 0 Corynebacterium
A00643:620:HFM7YDSX5:1:2124:8865:2472 ATCAGCCCGGGGCTTGGGCTAGGAC GGGTGTGTG 548476 0 Corynebacterium
A00643:620:HFM7YDSX5:1:2476:4001:29496 ATTCACCCTATAGGAGCCCGGGGCA TGCCCCGGG 1458266 0 Bordetella
答案1
awk
这里是有用的工具:
awk -F'\t' 'l[$3] {if ($5>n[$3]) {n[$3]=$5; l[$3]=$0} ; next}
{n[$3]=$5 ; l[$3]=$0}
END { for (i in l) {print l[i]}}' infile
-F'\t'
- 使用制表符作为字段分隔符
让我们从第二行开始:n[$3]=$5
将第 5 列中的数字存储在按第 3 列索引的数组中n
,并将整行存储在l
按相同索引的数组中。但是,这种情况只会在第 3 列中第一次出现唯一值时发生,因为:
l[$3] {...}
l
仅当数组中存在索引$3
(=第 3 列)的元素时,才会执行大括号中的命令。在这种情况下,将存储的值n
与第 5 列进行比较,并根据需要进行更新。next
方法跳到下一条记录,即文件的行。
END
- 循环遍历数组l
并返回具有唯一$3
且(第一个)最高值的所有行$5
。原始文件的排序是`不是保持。
答案2
使用任何排序和任何 awk:
$ sort -rnk5,5 file | awk '!seen[$3]++'
A00643:620:HFM7YDSX5:1:1150:15628:12743 CCTATCGTCGCTGGAATTCCCCGGG AGCCCGGGG 1458266 49 Bordetella
A00643:620:HFM7YDSX5:1:2476:4001:29496 ATTCACCCTATAGGAGCCCGGGGCA TGCCCCGGG 1458266 0 Bordetella
A00643:620:HFM7YDSX5:1:2124:8865:2472 ATCAGCCCGGGGCTTGGGCTAGGAC GGGTGTGTG 548476 0 Corynebacterium
A00643:620:HFM7YDSX5:1:1450:4001:4507 GGCGATCGAAATGTCAAGCCCGGGG TCTTGTGGT 585529 0 Corynebacterium
或单独使用任何 awk:
$ awk '
!($3 in max) || ($5 > max[$3]) { max[$3]=$5; line[$3]=$0 }
END { for (key in max) print line[key] }
' file
A00643:620:HFM7YDSX5:1:2476:4001:29496 ATTCACCCTATAGGAGCCCGGGGCA TGCCCCGGG 1458266 0 Bordetella
A00643:620:HFM7YDSX5:1:1150:15628:12743 CCTATCGTCGCTGGAATTCCCCGGG AGCCCGGGG 1458266 49 Bordetella
A00643:620:HFM7YDSX5:1:2124:8865:2472 ATCAGCCCGGGGCTTGGGCTAGGAC GGGTGTGTG 548476 0 Corynebacterium
A00643:620:HFM7YDSX5:1:1450:4001:4507 GGCGATCGAAATGTCAAGCCCGGGG TCTTGTGGT 585529 0 Corynebacterium
我们使用第一次设置!($3 in max)
来初始化,而不是基于任何值,因此即使最大值为 0 或负数,它也会起作用。最小/最大计算的经验法则是始终使用读取的第一个值进行初始化,而不是 0 或任何其他任意值。max[$3]
$3
$5
我们不需要将 FS 设置为选项卡,因为您说过所有字段始终存在,而且我可以告诉您,前 5 个字段中的任何一个字段都不可能有空白。
答案3
只需使用sort
:
sort -k3,3 -k5,5nr /tmp/my_acgt_file | sort -k3,3 -u
左侧将文件排序在第三个字段(最低的在前),然后,如果相等,则在第五个字段(最高的在前)。
右侧仅考虑(已排序)第三个字段,并通过保留它遇到的第一个字段并丢弃其他字段来保证它是唯一的。