【问题标题】:awk or other bioinformatics tools to filter vcfawk 或其他生物信息学工具来过滤 vcf
【发布时间】:2020-01-29 03:26:01
【问题描述】:

我正在尝试过滤 vcf 文件中的一些行,以下是行示例:

1   10505   rs548419688 A   T   100 PASS    AC=1;AF=0.000199681;AN=5008;NS=2504;DP=9632;EAS_AF=0;AMR_AF=0;AFR_AF=0.0008;E
UR_AF=0;SAS_AF=0;AA=.|||;VT=SNP
1   10506   rs568405545 C   G   100 PASS    AC=1;AF=0.000199681;AN=5008;NS=2504;DP=9676;EAS_AF=0;AMR_AF=0;AFR_AF=0.0008;E
UR_AF=0;SAS_AF=0;AA=.|||;VT=SNP
1   10511   rs534229142 G   A   100 PASS    AC=1;AF=0.000199681;AN=5008;NS=2504;DP=9869;EAS_AF=0;AMR_AF=0.0014;AFR_AF=0;E
UR_AF=0;SAS_AF=0;AA=.|||;VT=SNP
1   10539   rs537182016 C   A   100 PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=9203;EAS_AF=0;AMR_AF=0.0014;AFR_AF=0;E
UR_AF=0.001;SAS_AF=0.001;AA=.|||;VT=SNP
1   10542   rs572818783 C   T   100 PASS    AC=1;AF=0.000199681;AN=5008;NS=2504;DP=9007;EAS_AF=0.001;AMR_AF=0;AFR_AF=0;EU
R_AF=0;SAS_AF=0;AA=.|||;VT=SNP

假设我想提取 AMR_AF 大于 0.5 的行,但不知道如何使用 Awk 正则表达式来完成这项工作。试过vcftools,但没用。

【问题讨论】:

  • 欢迎来到 SO,很高兴您让我们知道您尝试了一些事情,请在您的问题中添加这些努力。
  • 另外请明确您要检查哪个字符串出现?由于您的问题尚不清楚。
  • vcf 标签用于日历文件格式;这肯定是别的东西吗?
  • 试试awk '{ split($0, x, /[\t;]AMR_AF=/) } x[2]>0.5' file.vcf
  • 在您的示例中,AMR_AF 没有大于 0.5 的行。

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


【解决方案1】:

请您尝试关注一下。

awk 'match($0,/AMR_AF=[0-9]+\.[0-9]+|AMR_AF=[0-9]+/) && substr($0,RSTART+7,RLENGTH-7)>0.5'  Input_file

解释: 使用 awkmatch 函数来匹配正则表达式 AMR_AF= digits.digitsAMR_AF=digits 并且每当此正则表达式在线匹配时,它就会设置 @ 987654326@ 和 RLENGTH 变量。 &&(AND 条件)检查 RSTART+7 的子字符串值是否到 RLENGTH-7 值大于 0.5,然后打印该行。

【讨论】:

    【解决方案2】:

    您可以在您选择的字段上拆分线,并检查拆分后元素的数值是否大于您的阈值。

    更详细地说,在,bar= 上拆分输入yes,foo=2,bar=0.23,baz=1 将产生一个包含yes,foo=20.23,baz=1 的数组。在 Awk 中,如果您将第二个元素与 0.2 进行比较,它会简单地将值的开头尽可能多地转换为数字,然后执行数字比较。

    这样

    awk '{ split($0, x, /[\t;]AMR_AF=/) } x[2]>0.5' file.vcf
    

    应该做你想做的。我们将该行拆分为x,并检查x[2] 的数值。

    正则表达式中的[\t;] 允许在字段名称前使用制表符或分号;完全笼统地说,也许您甚至应该使用 (^|[\t;]) 来允许匹配发生在行首。

    如果你想参数化这个,也许试试

    awk -v field="AMR_AF" -v thres=0.5 '{ split($0, x, "(^|[\t;])" field "=")) } x[2]>thres' file.vcf
    

    回想一下,Awk 从上到下处理每个输入行的脚本,其中每个脚本语句都有格式

    [ 条件 ] [ { 动作 } ]

    如方括号所示,这两个部分都是可选的——如果缺少条件,则动作将无条件执行;如果缺少 action,则默认为 { print $0 }。所以我们的脚本会先无条件地分割行,如果x[2]大于阈值则有条件地打印出来。

    GNU Awk 可以在多字符字段分隔符上进行拆分,因此您也可以使用 -F '[\t;]AMR_AF='

    awk -F '[\t;]AMR_AF=' '$2>0.5' file.vcf
    

    【讨论】:

    • 非常感谢您的快速回复!只是一个简单的问题:如果我想提取 AMR_AF=;AFR_AF 之间的值,并使用正则表达式打印出数值呢?
    • 这应该很容易理解; split 两次。您还可以使用 RavinderSingh13 的答案中的match() 逻辑并计算来自RSTARTRLENGTH 的偏移量来找出提取子字符串的索引,但我觉得它相当麻烦。
    【解决方案3】:

    使用bcftools

    bcftools view -i 'INFO/AMR_AF > 0.5' myFile.vcf
    

    更多选项请参阅bcftools manuals

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-04
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多