数据分析中,我们经常需要根据某一列的信息来融合多个文本。达到这个目的的方法有很多,这里介绍一下通过命令行join
进行的做法。
假如说我们有两个文件example.bed
与example_lengths.txt
(如下),前者包括了染色体与起始位点信息,后者包括了染色体长度信息,我们想要根据染色体编号来合并两个文本。
$ 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
$ cat example_lengths.txt
chr1 58352
chr2 39521
chr3 24859
- 在合并文本之前,一个关键的步骤是将文本排序(或者通过
-c
确定文本是否已经排序完毕,见sort
):
$ sort -k1,1 example.bed > example_sorted.bed
$ sort -c -k1,1 example_lengths.txt;echo $?
0
- 通过命令
join -1 <第一个文件的第a列> -2 <第二个文件的第b列> <第一个文件名> <第二个文件名>
来合并两个文本:
$ join -1 1 -2 1 example_sorted.bed example_lengths.txt > example_with_lengthes.txt
cat example_with_lengthes.txt
chr1 10 19 58352
chr1 26 39 58352
chr1 32 47 58352
chr1 40 49 58352
chr1 9 28 58352
chr2 35 54 39521
chr3 11 28 24859
chr3 16 27 24859
以上已经达到了合并文本的目的,不过有一个关键点需要注意:
因为两个文件都包含了相同的染色体编号,join
前后第一个文件行数是不变的(如下)。
$ wc -l example_sorted.bed example_with_lengthes.txt
8 example_sorted.bed
8 example_with_lengthes.txt
16 total
不过如果第二个文件里只包括2条染色体长度信息的话,结果怎样呢?(如下)
$ head -n2 example_lengths.txt > example_lengths_alt.txt
$ join -1 1 -2 1 example_sorted.bed example_lengths_alt.txt
chr1 10 19 58352
chr1 26 39 58352
chr1 32 47 58352
chr1 40 49 58352
chr1 9 28 58352
chr2 35 54 39521
可以看到,合并后的文本凡是涉及3号染色体的行都被去掉了(取了两个文件的交集)。如果我们想要保留某个文件未匹配的列的话,可以指定参数-a <文件号>
(根据文件位置指定1或者2),例如:
$ join -1 1 -2 1 -a 1 example_sorted.bed example_lengths_alt.txt
chr1 10 19 58352
chr1 26 39 58352
chr1 32 47 58352
chr1 40 49 58352
chr1 9 28 58352
chr2 35 54 39521
chr3 11 28
chr3 16 27
可见第一个文件的染色体编号列都被保留了,未匹配到长度的行以空白填充。
网友评论