第4章 FILTER和INFO字段:过滤标志与变异位点属性
VCF文件里除了基因型,还有两列信息特别关键——FILTER和INFO。
说白了,FILTER告诉你这个位点“能不能用”,INFO告诉你这个位点“具体怎么样”。
我刚开始做变异检测时,经常把这两个字段混在一起。后来被坑了几次才发现:分清它们,是做好注释分析的起点。
核心一句话:
- FILTER → 质检结果(通过/不通过/未检测)
- INFO → 位点属性(频率、深度、质量指标等)
4.1 FILTER字段:PASS与非PASS
FILTER字段位于VCF文件的第7列。它记录的是:这个变异位点是否通过了质量过滤。
快速理解:
PASS→ 位点通过了所有预设过滤条件,可以放心使用.→ 未进行任何过滤,这意味着状态不明,需要谨慎- 具体名称 → 如
QD<2.0、FS>60,表示触发了某个过滤规则
为什么会这样?
举个例子。你想想看,一个位点虽然被检测出来,但测序深度只有1X,或者链偏好性极强,这样的位点你敢信吗?
GATK VQSR或硬过滤后,FILTER字段会写清楚这个位点“有没有问题”。我个人习惯是先看一眼FILTER的分布情况,再决定怎么往下走。
避坑提醒:
我曾经在一个项目里,看到的FILTER值全是“.”,以为是所有位点都通过了。后来才发现,是上游没跑过滤步骤。结果整个关联分析都是基于未过滤的数据做的……那感觉,你懂的。
记住:. ≠ PASS。. 表示“没检测”,PASS 才表示“没问题”。
4.1.1 常见FILTER标志速查
| FILTER值 | 含义 | 处理建议 |
|---|---|---|
| PASS | 通过所有过滤 | 放心使用 |
| . | 未进行过滤 | 建议自行过滤后再用 |
| VQSRTrancheSNP99.90to100.00 | VQSR分箱过滤 | 低质量区域,慎用 |
| SB | 链偏向性过高 | 很可能是假阳性 |
| LowQual | 低质量(GATK默认标记) | 建议直接排除 |
我建议你在做批次关联分析之前,先用bcftools或vcftools看一眼FILTER的分布:
# 统计FILTER字段各值的出现次数
bcftools query -f '%FILTER\n' your.vcf.gz | sort | uniq -c | sort -rn
# 保留PASS位点
bcftools view -f PASS your.vcf.gz -o pass_only.vcf.gz
嗯,这里要注意:bcftools view -f PASS 只保留FILTER为PASS的位点。如果你想保留PASS和.,就得用 -f .,PASS。我每次都会检查一下,不然容易漏。
4.2 INFO字段:变异位点的属性库
INFO字段是VCF的“属性大本营”。它用key=value的形式,记录了这个位点的各种特征。
说白了,INFO就是一堆预先计算好的注释指标。你用bcftools annotate加进去的dbSNP ID、千人基因组频率、CADD分值,全都会写进INFO字段。
INFO字段结构示例:
AC=123;AF=0.0246;AN=5000;DP=12500;FS=3.8;QD=28.1;SOR=0.54;MQRankSum=0.23
每个标签对应一个具体属性,分号分隔,键值对形式。
我在项目中遇到过好几次,有人把AF(等位基因频率)和MAF(最小等位基因频率)搞混。虽然大部分情况下AF就是MAF,但严格来说AF是ALT的等位基因频率,不是自动取最小值。使用时最好确认一下注释来源。
4.2.1 常用INFO标签分类
| 类目 | 常见标签 | 说明 |
|---|---|---|
| 频率统计 | AC/AF/AN | 等位基因计数、频率、总等位基因数 |
| 测序深度 | DP | 覆盖该位点的总reads数 |
| 质量度量 | QD / FS / SOR / MQ | QualByDepth / FisherStrand / StrandOddsRatio / RMSMappingQuality |
| 功能注释 | ANN / CSQ / ENSG | 由SnpEff / VEP 等工具注释的功能信息 |
| 数据库交集 | dbSNP / CLNSIG / CADD | 与外部数据库交集的标识与风险评分 |
你想想看,一次批次分析动辄几十万甚至上百万位点,如果不把INFO标签搞清楚,后面根本没法做。
4.2.2 查看INFO字段定义
VCF文件头部(##INFO开头的行)会定义每个标签的类型和描述。我建议你先用grep抓出来看看:
# 查看所有INFO标签定义
bcftools head your.vcf.gz | grep "^##INFO"
# 只看某几个关键标签的详细定义
bcftools head your.vcf.gz | grep -E "^##INFO=
输出内容大致长这样:
##INFO=
##INFO=
##INFO=
个人技巧:我一般写分析脚本前,都会跑一遍这个命令,把INFO标签表先列出来。这样后面用bcftools query -f '%INFO/TAG'取数据时,不会写错标签名。
4.2.3 自定义INFO标签
你完全可以往INFO字段里加自己的计算结果。比如你自己算了一个群体分化指数FST,就可以用bcftools annotate加进去:
# 先准备一个带注释的文本文件(tabix索引过)
echo -e "#CHROM\tPOS\tID\tREF\tALT\tFST\n1\t1000\t.\tA\tG\t0.15" > my_anno.txt
bgzip my_anno.txt && tabix -s1 -b2 -e2 my_anno.txt.gz
# 把FST写入INFO字段
bcftools annotate -a my_anno.txt.gz -c CHROM,POS,ID,REF,ALT,-,FST -h my_header.txt input.vcf.gz -o output.vcf.gz
注意:自定义标签必须事先在VCF头部定义好格式(##INFO行)。我刚开始做的时候忘了加头部定义,直接报错,折腾了半天。
4.3 FILTER与INFO的联合使用
两者联合起来才是完整套路。我的常规流程是:
- 第一步:基于FILTER做硬过滤 → 先用PASS去掉低质量位点
- 第二步:基于INFO做软筛选 → 根据DP、QD、FS等指标进一步挑出高质量位点
- 第三步:提取INFO注释 → 用
bcftools query或自定义脚本提取你需要的属性
举个例子,我要分析一批全外显子数据中的罕见致病突变,就会这样操作:
# 步骤1:只保留PASS位点
bcftools view -f PASS all_sites.vcf.gz -o pass_sites.vcf.gz
# 步骤2:按深度和质量进一步过滤
bcftools view -i 'DP>10 & QD>2.0 & FS<60.0' pass_sites.vcf.gz -o filtered.vcf.gz
# 步骤3:提取目标INFO标签
bcftools query -f '%CHROM\t%POS\t%REF\t%ALT\t%AF\t%ANN\n' filtered.vcf.gz > extracted_ann.txt
避坑经验:
我曾经在一个批次效应分析项目里,只做了FILTER过滤就跑去跑PCA了。结果发现有几个批次明显偏移,排查了三天才找到原因——INFO字段里的DP在批次间差异巨大。原来有两个批次用的是不同的测序平台,覆盖深度差异导致批次效应。
所以,FILTER解决的是“质量能不能用”,INFO解决的是“属性有什么影响”。批次关联分析里,两者必须同时关注。
4.4 实战:快速查看VCF中FILTER和INFO分布
我一般拿到一个新的VCF文件,会先跑下面这几行命令,快速摸清FILTER和INFO的情况:
# 1. 看FILTER分布
bcftools query -f '%FILTER\n' your.vcf.gz | sort | uniq -c | sort -rn
# 2. 看几条具体位点的FILTER和INFO
bcftools query -f '%CHROM\t%POS\t%FILTER\t%INFO/DP\t%INFO/AF\t%INFO/QD\n' your.vcf.gz | head -20
# 3. 检查INFO标签完整性(看有没有缺失值)
bcftools query -f '%INFO/DP\n' your.vcf.gz | grep -c '\.'
记住,良好的数据洞察力,是从每次拿到数据后先跑几个统计命令开始的。
本章要点总结:
- FILTER → 位点过滤标志,PASS表示可信,非PASS或被.表示谨慎处理
- INFO → 位点属性库,包含频率、深度、质量、功能注释等关键信息
- 联合使用 → 先FILTER硬过滤,再INFO软筛选,最后提取目标属性
- 自定义扩展 → INFO支持自定义标签,但需先定义头部
- 批次分析必做 → 检查FILTER和INFO的分布,避免批次间系统偏差