【问题标题】:Find matching key in two large sorted text files and compare values (VCF-files)在两个大的排序文本文件中查找匹配键并比较值(VCF 文件)
【发布时间】:2016-11-03 20:34:35
【问题描述】:

我正在寻找一种有效的解决方案来过滤两个数据集。基本上,我只想保留一个文件中没有缺失的行作为它们的键列,并且在两个文件中都没有值“0/0”。

输入数据(对于那些感兴趣的人,我为这个问题简化的基因组 VCF 文件)具有以下特征:

  • 第 1 列和第 2 列一起是按数字排序的唯一标识符
  • 第 3 列以值 0/0、0/1 或 1/1 开头

理想情况下,该脚本会执行以下操作:

  1. 遍历 sample1.dat 中的每一行并在 sample2.dat 中查找相同的标识符
  2. 如果在 sample2.dat 中找不到来自 sample1.dat 的标识符,则什么也不做
  3. 如果两行都包含“0/0”,则什么也不做
  4. 如果一行或两行不包含“0/0”,则将这两行写入各自的输出 .

输入

sample1.dat

1      1001  0/0:8:8:99:PASS
1      1002  0/0:8:8:99:PASS
1      1003  0/1:5,3:8:99:PASS,PASS
2      1234  0/0:8:8:99:PASS # not present in sample2
2      2345  1/1:8:8:99:PASS

sample2.dat

1      1001   0/0:8:8:99:PASS
1      1002   0/1:5,3:8:99:PASS,PASS
1      1003   0/0:8:8:99:PASS
2      2345   1/1:8:8:99:PASS
2      3456   0/1:8:8:99:PASS # not present in sample1

输出

sample1_out.dat

1      1002  0/0:8:8:99:PASS
1      1003  0/1:5,3:8:99:PASS,PASS
2      2345  1/1:8:8:99:PASS

sample2_out.dat

1      1002   0/1:5,3:8:99:PASS,PASS
1      1003   0/0:8:8:99:PASS
2      2345   1/1:8:8:99:PASS

在这种情况下,不会打印 1-1001,因为它们都有值“0/0”,并且不会打印 2-1234 和 2-3456,因为它们都不存在于两个文件中。

一些注意事项:

  • 文件大约 260GB,但我可以轻松地将它们拆分为多个最大 18GB 的​​文件(我基本上将它们拆分为染色体)
  • 我的机器上的可用内存大约是 128GB
  • 第 1 列和第 2 列已经一起按数字顺序排序了

非常感谢任何帮助!

【问题讨论】:

  • 你试过什么???
  • 我拥有的工具非常有限...... GNU join 然后 grep -v 太慢了。我尝试了一些awk-scripts,但是由于它没有考虑到两列是排序的,所以它也非常慢

标签: perl unix awk bioinformatics vcf-variant-call-format


【解决方案1】:

awk 来救援!可能您需要先拆分文件,对于每个块您都可以这样做

$ function f { awk -v OFS='\t' '{print $1"~"$2,$0}' $1; }; 
  join <(f file1) <(f file2) | 
  awk -v OFS='\t' '$4!~/0\/0/ || $7!~/0\/0/ 
                     {print $2,$3,$4 > "file1.out"; 
                      print $5,$6,$7 > "file2.out"}'    

说明join 做匹配对应记录的工作,但需要通过合并前两个字段来创建合成键。输出包含我们需要的所有信息,将结果的相应字段和输出部分中的“0/0”逻辑应用到相应的输出文件。

$ head file{1,2}.out                          

==> file1.out <==                                                                                                     
1       1002    0/0:8:8:99:PASS
1       1003    0/1:5,3:8:99:PASS,PASS
2       2345    1/1:8:8:99:PASS

==> file2.out <==
1       1002    0/1:5,3:8:99:PASS,PASS
1       1003    0/0:8:8:99:PASS
2       2345    1/1:8:8:99:PASS

你可能会更好地参数化文件名,包括输入和输出。

【讨论】:

  • 效果很好!我不知道您可以在另一个命令中使用类似的 awk 函数,这样可以节省大量不必要地写入磁盘的时间。仅供参考:分析最小染色体(chr20、4.7G、53M 行)的两个完整 VCF 文件可在 10 分钟内完成。谢谢!
  • 很高兴为您提供帮助。请注意,它不是 awk 函数,而是包装 awk 以消除重复的 bash 函数。继续研究。最终,我们都会受益。
猜你喜欢
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-27
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多