第1章:VCF格式详解——结构、字段与规范

做生物信息学的人,每天都得跟VCF打交道。

VCF,全称是Variant Call Format,变异检测的标准输出格式。说白了,它就是描述样本在基因组上“哪里不一样、怎么不一样”的文本文件。

我刚开始接触NGS数据分析那会儿,觉得这就是个普通的表格。直到有一次项目里,因为我忽略了VCF头部的几个关键字段,导致下游注释全乱套……嗯,从那以后,我再也不敢小看这个格式了。这一章,我把我这些年踩过的坑和沉淀下来的经验,一起给你理清楚。

1.1 VCF文件的三段式结构

一个标准的VCF文件,由三部分组成:元数据行(以##开头)、列标题行(以#CHROM开头)、数据行(紧跟在标题行后面)。

我的习惯是,先把头部过一遍,再看数据。为什么呢?因为元数据里藏着你对数据的“解释规则”。

区段标记作用
元数据行##定义文件版本、INFO/FORMAT字段含义、过滤条件、参考基因组等
列标题行#CHROM固定10列核心字段 + 若干样本列
数据行无逐行记录每个变异的具体信息

给你看个完整的VCF头部示例:

##fileformat=VCFv4.2
##fileDate=20250315
##source=GATK4.2.0.0
##reference=hg38
##contig=<ID=chr1,length=248956422>
##INFO=<ID=DP,Number=1,Type=Integer,Description="Total Depth">
##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">
##FORMAT=<ID=AD,Number=R,Type=Integer,Description="Allelic depths">
##FILTER=<ID=q30,Description="Quality below 30">
#CHROM  POS  ID  REF  ALT  QUAL  FILTER  INFO  FORMAT  sample_01

核心记忆点:VCF头部中的##INFO和##FORMAT行,定义了数据行里INFO列和FORMAT列到底能解析出哪些子字段。没有这些定义,数据就是一堆数字和字母,毫无意义。

1.2 必修的10列核心字段

每一行数据的前8列是强制信息,加上FORMAT和样本列,组成了VCF的骨架。我挨个解释一下,尤其是那些容易搞混的。

列号字段名类型说明
1CHROMString染色体/contig名称,必须与头部##contig一致
2POSInteger变异在染色体上的起始位置(1-based)
3IDString变异标识符,常见的是dbSNP的rs号;无则填.
4REFString参考基因组上的等位碱基
5ALTString替代等位碱基,多个用逗号分隔;无变异填.
6QUALFloat变异质量评分(Phred scale),越高越可靠
7FILTERString过滤状态:PASS或头部定义的过滤器名称;未过滤填.
8INFOString以键值对形式存储变异的附加信息,如DP、AF等
9FORMATString定义样本列各子字段的分隔顺序,如GT:AD:DP
10+样本列String每个样本一个列,值与FORMAT定义的字段一一对应

这里提一个我踩过的坑。POS是1-based,而很多其他工具用0-based。我曾经在做坐标转换时,忘了这个偏移,结果变异位置全串位了。所以我的习惯是:拿到VCF第一件事,确认所有工具链是否统一使用1-based坐标。

常见陷阱:我见过不少新手,把FILTER列全是PASS当成过滤好的数据。不对,FILTER列里可能有些行是.qc_fail之类的,筛选的时候必须用bcftools filter -i 'FILTER="PASS"'这类命令。这个细节,我吃过亏。

1.3 INFO vs FORMAT:你真的分清了吗?

这是VCF最让人纠结的地方。好多同行问过我,INFO和FORMAT到底啥区别?

INFO:存储的是“这个变异本身的属性”。不管你有几个样本,这个变异的信息是共享的。比如总体深度DP、等位基因频率AF。

FORMAT:存储的是“每个样本在这个位点上的个性化信息”。每个样本的基因型GT、等位基因深度AD、基因型质量GQ,都是按样本单独计算的。

我整理了一个对比表,你一看就明白:

特性INFOFORMAT
范围位点级别,所有样本共享样本级别,每个样本独自有值
常见字段DP、AF、AC、AN、MQ、MQRankSumGT、AD、DP、GQ、PL、GL
存储位置第8列(INFO列)第9列定义,第10+列填充
用途全局质量评估、人群频率、注释个体基因型、测序深度、样本质控

举个例子,一行典型的VCF数据可能是这样的:

chr1  100  rs12345  A  G  50.5  PASS  DP=100;AF=0.45  GT:AD:GQ  0/1:30,70:99

这里DP=100;AF=0.45在INFO里,说明该位点整体覆盖深度100,人群频率0.45。而GT:AD:GQ是FORMAT头,对应样本列的值0/1:30,70:99,代表杂合突变,参考等位基因深度30,替代等位基因深度70,基因型质量99。

我的习惯是:写脚本解析VCF时,先从头部提取INFO和FORMAT的定义字典。这样不管VCF版本怎么变,解析逻辑都能自适应。像pysam或者cyvcf2这类库,都内置了这个能力。

1.4 常见规范与避坑指南

VCF规范在实际使用中,有不少“潜规则”。我挑几个最要命的跟你唠唠。

  • REF和ALT的大小写:必须用大写字母。我见过samtools mpileup输出的vcf给了小写,结果下游注释工具直接报错。你想想看,这种低级错误,排查起来多费劲。
  • 多等位基因位点:ALT可以用逗号分隔写多个,比如A,G。但要注意,样本的GT字段里,如果ALT有两个以上,数字编号1、2分别对应ALT列的顺序。
  • ID字段的规范:原则上保持唯一且稳定。有些变异缺失dbSNP ID,就用.占位。但我在合并多个VCF时,经常遇到相同位点ID不一致的情况。这时候,我个人建议使用bcftools annotate --set-id重新赋予统一的ID。
  • VCF必须压缩和索引:正规用法是bgzip压缩+.tbi或.csi索引。我曾经图省事用gzip压缩,结果很多工具不认,白白浪费半天时间。
命名的艺术:染色体名称一定要统一。有的VCF用1,有的用chr1。做合并或对比时,不改就会匹配不上。我的建议是:在生成VCF阶段,明确指定参考基因组版本,比如--reference hg38.fa,就基本能避免这个问题。

1.5 实战验证:读懂一个完整的VCF行

来,咱们一起拆一个真实常见的VCF示例。假设文件内容如下:

##fileformat=VCFv4.2
##FILTER=<ID=PASS,Description="All filters passed">
##INFO=<ID=DP,Number=1,Type=Integer,Description="Total depth">
##INFO=<ID=AF,Number=A,Type=Float,Description="Allele frequency">
##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">
##FORMAT=<ID=AD,Number=R,Type=Integer,Description="Allelic depths">
##FORMAT=<ID=GQ,Number=1,Type=Integer,Description="Genotype quality">
#CHROM  POS  ID  REF  ALT  QUAL  FILTER  INFO  FORMAT  sample_01  sample_02
chr1  123456  .  T  C  60  PASS  DP=150;AF=0.33  GT:AD:GQ  0/1:40,110:99  1/1:5,95:85

我来一句句解释:

  • 位置:chr1上第123456个碱基,T→C的单核苷酸变异。
  • 质量:Phred评分60,错误概率仅为百万分之一。这个值很靠谱。
  • FILTER:通过所有过滤。
  • INFO:整体深度150,等位基因频率0.33。
  • FORMAT定义:每个样本提供GT、AD、GQ三列。
  • sample_01:杂合突变(0/1),参考等位基因深度40,突变等位基因深度110,GQ=99。
  • sample_02:纯合突变(1/1),参考深度5,突变深度95,GQ=85。
实践出真知。如果你手头有VCF文件,我建议你养成三查的习惯:查头部定义、查染色体命名、查FORMAT字段数量与样本列是否对得上。能做到这三点,VCF解析的错误率至少降低80%。

好了,关于VCF格式的基本功,就讲到这里。你记住这三点就行:三段式结构、10列强制字段、INFO和FORMAT各司其职。这些是后续章节所有知识图谱构建的基石。

VCF文件结构知识图谱 VCF文件 元数据行 (##) 列标题行 (#CHROM) 数据行(变异行) fileformat INFO定义 FORMAT定义 FILTER定义 10列固定字段 CHROM / POS / ID REF / ALT / QUAL FILTER / INFO / FORMAT + 样本列 数据行内容 染色体 位置 ID REF ALT QUAL FILTER INFO → DP;AF FORMAT → GT:AD:GQ ⚠ 实战关键原则 1. 先解析头部INFO/FORMAT定义,再解析数据行 2. POS为1-based,注意与其他工具坐标系统统一