第2章 VCF格式详解
VCF,全称Variant Call Format,是生物信息学里最通用的变异存储格式。记得我刚入行时,被这个格式的字段数量吓了一跳——不就是记录一个变异位点吗?怎么列了那么多东西?后来才明白,每个字段背后都藏着一段实验历史和计算逻辑。
今天我们就把它拆开揉碎,从文件结构到场位含义,一路讲清楚。
2.1 VCF文件整体结构
一个标准的VCF文件,你可以想象成三块积木堆叠:元信息头、列标题行、数据行。缺一不可。
先看一个完整的VCF文件头(我通常用 grep -v "^##" 快速跳过注释去看数据):
##fileformat=VCFv4.2
##fileDate=20240101
##source=GATK4
##contig=<ID=chr1,length=248956422>
##INFO=<ID=DP,Number=1,Type=Integer,Description="Total Depth">
##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT SAMPLE1 SAMPLE2
chr1 12345 . A G 500.90 PASS DP=100 GT:GQ 0/1:99 1/1:99
结构清楚吗?我们来逐个拆解。
关键点:所有以 ## 开头的行都是元信息头,# 开头的只有一行——那是列标题。数据行没有 # 前缀。
2.2 元信息头(Meta-information Lines)
元信息头以 ## 开头,每行一个键值对或结构体。它的作用类似“数据字典”:告诉下游工具每个字段的含义和类型。
常见的元信息头包括:
##fileformat—— VCF规范版本,我现在用VCFv4.2,有些旧数据集是4.1或4.0。##INFO—— 描述INFO列里的字段。##FORMAT—— 描述FORMAT列里的字段。##FILTER—— 自定义过滤标签。##contig—— 参考基因组染色体信息。
举个例子,我们想定义一个自定义INFO字段:
##INFO=<ID=AF,Number=A,Type=Float,Description="Allele Frequency for each alt allele">
这里 Number=A 表示该字段值的数量会随ALT等位基因个数变化。我曾在项目中因为Number写错,导致下游bcftools query解析时报错,浪费了半天才排查出来。这个坑,各位一定要记住。
再看FORMAT定义:
##FORMAT=<ID=AD,Number=R,Type=Integer,Description="Allelic depths for each allele">
Number=R代表每个参考等位基因+每个ALT等位基因各一个值。这些元信息行不是摆设,bcftools、PLINK等工具全靠它们来解析字段。
2.3 列标题与数据行字段详解
列标题行固定9个必填列,后面跟着一个或多个样本列。这9列是:CHROM, POS, ID, REF, ALT, QUAL, FILTER, INFO, FORMAT。我们逐一说清楚。
| 列名 | 含义 | 典型值 | 课堂提醒 |
|---|---|---|---|
| CHROM | 染色体/contig名称 | chr1, chrX, chrM | 必须与参考基因组一致 |
| POS | 在染色体上的位置(1-based) | 12345 | 很多工具默认用0-based,注意转换 |
| ID | dbSNP的rs编号或自定义ID | rs12345 或 . | 点号表示无ID |
| REF | 参考等位基因序列 | A, AT, CTG | 必须是参考基因组上真实序列 |
| ALT | 替代等位基因序列,可多个 | G, T, CT, <DEL> | 多个ALT用逗号分隔 |
| QUAL | Phred质量评分 | 500.90 | 值越高表示变异可信度越高 |
| FILTER | 过滤状态 | PASS, q20, LowQual | PASS表示通过所有过滤器 |
| INFO | 变异的附加信息,键值对 | DP=100;AF=0.45 | 多个键值对用分号分隔 |
| FORMAT | 样本基因型字段名称列表 | GT:GQ:AD | 冒号分隔的字段名 |
我曾经踩过的坑:在同一份数据里,我把CHROM列写成了“chr1”但参考基因组用“1”开头,结果bcftools merge死活合并不了。CHROM命名必须和参考FASTA的contig名完全一致,大小写都不能错。
2.4 样本列与FORMAT字段
从第10列开始,每一列对应一个样本。第一个样本列的值必须与FORMAT列定义的顺序对应——用冒号分隔。
最常见的FORMAT字段包括:
- GT(Genotype):0/0表示纯合参考,0/1表示杂合,1/1表示纯合变异。注意相位用
|,非相位用/。 - GQ(Genotype Quality):Phred质量的二重评分。
- DP(Read Depth):覆盖该位点的总读数。
- AD(Allelic Depth):每个等位基因的读数列表。
来看一个具体的样本列:
FORMAT SAMPLE1
GT:AD:DP:GQ 0/1:10,8:18:99
这表示样本SAMPLE1的基因型为杂合(0/1),参考等位基因深度10,ALT深度8,总深度18,GQ为99(非常可靠)。
我在做药物靶点关联分析时,经常需要把GT字段转化为“0,1,2”的剂量编码,这里有一个小技巧:
bcftools +dosage -o output.vcf input.vcf
不过要注意,如果样本列有丢失数据(用 . 表示),必须先过滤掉。
2.5 INFO字段详解(药物靶点关联常用)
INFO列里可以塞很多信息,在药物基因组学中,我们关注几个关键标签:
| INFO标签 | 含义 | 药物靶点场景 |
|---|---|---|
| DP | 总深度 | 低深度可能引起假阳性 |
| AF | 等位基因频率 | 稀有变异(AF<0.01)可能影响药物代谢 |
| AN | 总等位基因数 | 用于计算缺失率 |
| AC | ALT等位基因计数 | 结合AF判断变异丰度 |
比如要快速提取所有AF大于0.05且深度超过30的位点:
bcftools view -i 'INFO/DP > 30 & INFO/AF > 0.05' input.vcf
这个命令我几乎每天都会用到,很顺手。
2.6 一张图看懂VCF结构
下面这张SVG图把VCF的骨架和关键字段整理在了一起,方便你对照回忆:
个人习惯:我拿到一个陌生的VCF文件,第一件事就是跑 bcftools head -n 20 | less 看元信息头,确认FORMAT和INFO字段的定义,否则很容易把GT和AD理解反。
2.7 实战小技巧:快速验证VCF格式
检测VCF是否规范,我常用的三个命令:
- 检查行数统计:
bcftools stats input.vcf - 查看所有样本名:
bcftools query -l input.vcf - 提取特定字段:
bcftools query -f '%CHROM\t%POS\t%REF\t%ALT[\t%GT]\n' input.vcf
你看,其实掌握VCF格式没那么难。把9个固定列和样本列之间的关系理清,后面做知识图谱关联时,你就能准确地从VCF里提取药物靶点相关的变异了。
嗯,VCF格式我们就讲到这里。它的每一个字段都像基因组的“指纹印”,读懂了,你就能跟数据对话了。