对数据进行排序的好处有:
- 提高特定程序的运行速度,这些程序(后续会介绍)在输入排序过的数据会大大减少运行时间
-
sort | uniq
作为一个常用的连招使用保留唯一值(下一节具体介绍)。
这里我们介绍一下Unix的排序命令sort
的用法。
以example.bed
文件(如下)为例 :
$ cat example.bed
chr1 26 39
chr1 32 47
chr3 11 28
chr1 40 49
chr3 16 27
chr1 9 28
chr2 35 54
chr1 10 19
直接将此文件传入sort
命令,sort
命令按照由第一列到最后一列,字母表的顺序对文件各行进行排序:
$ sort example.bed
chr1 10 19
chr1 26 39
chr1 32 47
chr1 40 49
chr1 9 28
chr2 35 54
chr3 11 28
chr3 16 27
注:sort
命令默认的列之间分隔符为\t
,可以使用-t
指定(例如对于csv文件使用-t,)。
文件第二列按字母顺序排序存在明显的问题,之前我们提过一种解决方式是在数字前面补0。实际上sort
命令可以使用-k
参数指定需要排序的列与排序方式(见下方代码)。
$ sort -k1,1 -k2,2n example.bed
chr1 9 28
chr1 10 19
chr1 26 39
chr1 32 47
chr1 40 49
chr2 35 54
chr3 11 28
chr3 16 27
解释:
-k
后面接以逗号分隔的一组数字{start, end}
的意思是排序从start
列开始到end
列结束,那么-k1,1
的意思就是只根据第一列排序,另外指定的-k2,2n
意思是第一列顺序一样的话还要根据第二列按照数字顺序排序。如果所有指定的列都按照数字顺序排序的话,可以在前面添加-n
参数。
有时候包含的数字的字符串我们依然想要通过数字排序,例如example2.bed
文件(如下)的染色体编号:
$ cat example2.bed
chr2 15 19
chr22 32 46
chr10 31 47
chr1 34 49
chr11 6 16
chr2 17 22
chr2 27 46
chr10 30 42
可以通过-V
参数进行排序:
$ sort -k1V -k2,2n example2.bed
chr1 34 49
chr2 15 19
chr2 17 22
chr2 27 46
chr10 30 42
chr10 31 47
chr11 6 16
chr22 32 46
排序操作吃算力,如果我们能够确定一个文件是已经排序好的文件的话,就没必要重新排序了。sort
命令的-c
参数可以确定文件是否排序完毕了:
$ sort -k1,1 -k2,2n example.bed > example_sorted.bed
$ sort -k1,1 -k2,2n -c example_sorted.bed
$ echo $?
0
$ sort -k1,1 -k2,2n -c example.bed
$ echo $?
1
以上结果看出,对排序过的文件检查的返回值为0,而未排序过的文件检查的返回值为1。
下面介绍一下sort
的进阶用法,首先sort
可以采用临时缓存策略排序比可用内存更大的数据,例如:
$ sort -k1,1 -k4,4n -S2G Mus_musculus.GRCm38.75_chr1.gtf
其中-S
参数表示sort
可以使用2G的内存,数据量更大时采用临时缓存。
sort
还可以指定CPU的核数(--parallel
):
$ sort -k1,1 -k4,4n --parallel 4 Mus_musculus.GRCm38.75_chr1.gtf
值得注意的是,并行运算有固定成本,当数据量小的时候运算速度反而更慢。除非你的数据量足够大,否则不要使用这样的性能优化。