根据另一列的值过滤重复项

根据另一列的值过滤重复项

我有以下数据框示例。您可以看到第三列的元素可以重复。我想保留第 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

左侧将文件排序在第三个字段(最低的在前),然后,如果相等,则在第五个字段(最高的在前)。

右侧仅考虑(已排序)第三个字段,并通过保留它遇到的第一个字段并丢弃其他字段来保证它是唯一的。

相关内容