第1章 VCF格式概述
我个人做变异分析这么多年,接触过的格式少说也有十几种。但要说哪个最绕不开,那还得是VCF。说白了,VCF就是变异 calling 结果的通用语言。你不管用什么软件跑的变异检测,最终要想做注释、做筛选、做可视化,几乎都得回到VCF这个格式上来。
本章咱们就把VCF的骨架先摸清楚。我不打算一上来就丢一长串规范文档,咱们从实际文件的结构入手,把每个字段是干什么的、为什么要这么设计,都掰扯明白。
1.1 VCF文件的三大块
一个标准的VCF文件,其实就三部分内容。我习惯这样记:元数据、表头、数据行。元数据告诉你这个文件是怎么来的,表头告诉你每一列代表什么,数据行就是真正的变异记录。拿一个最简单的VCF文件片段来说:
##fileformat=VCFv4.2
##source=myPipeline_v1.0
##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
chr1 10000 . A G 500.23 PASS DP=120 GT 0/1
元数据行以两个#开头,表头行以一个#开头,数据行不要#。这个区分其实挺好记的。我在项目初期带新人时,经常看到有人把元数据和表头混着写,结果解析工具直接报错。嗯,这里要注意,元数据必须放在表头之前,顺序不能乱。
1.2 核心字段逐个拆解
表头后面的数据行,固定有8个核心字段,再加上后面的样本列。我把它们的含义和常见坑点整理成了一张表:
| 字段 | 含义 | 我遇到过的坑 |
|---|---|---|
| CHROM | 染色体名称,需与参考基因组一致 | 引物设计时发现染色体名前带"chr"和不带混用,直接导致下游报错 |
| POS | 变异在染色体上的起始位置(1-based) | 1-based的坐标容易和BED格式(0-based)搞混,我吃过这个亏 |
| ID | 已知变异的标识符,如dbSNP的rs号 | 常用点号占位,不代表没有ID |
| REF | 参考基因组上的等位碱基 | 长度可为多碱基,但必须与参考一致 |
| ALT | 检测到的替代等位碱基 | 多个等位基因用逗号分隔,不要用空格 |
| QUAL | Phred质量分数 | 分数越高越可靠,但我见过有人直接当p-value用,完全不是一回事 |
| FILTER | 过滤标签 | PASS表示通过,否则是具体失败原因 |
| INFO | 位点级别的附加信息 | 使用key=value形式,多个用分号隔开 |
FILTER字段的潜规则:PASS是唯一被广泛认可的通过标记。如果你用点号或者空值代替,很多工具会默认当作未过滤,可能把一些假阳性也放进来。我个人建议,经过过滤的VCF一定要写PASS,别偷懒。
1.3 元数据说了什么
元数据这部分,初学者容易忽略。其实它就像菜的包装说明,告诉你这包数据过了哪些处理、用了什么参考基因组、定义了哪些INFO键和FORMAT键。
最常用到的元数据标签有这么几类:
- fileformat:VCF规范的版本号,目前主流是VCFv4.2
- source:生成该VCF的软件或流程
- reference:参考基因组的路径或版本
- contig:定义每条染色体的ID和长度
- INFO:声明INFO字段中的键,包含类型、数量和描述
- FORMAT:声明FORMAT字段中的键,包含类型、数量和描述
- FILTER:声明FILTER字段中出现的过滤原因
为什么要花篇幅讲元数据?因为下游工具,比如SnpEff、ANNOVAR、VEP,它们的解析逻辑高度依赖元数据中的声明。如果你自己写脚本处理VCF,也一定要先提取元数据做校验。我曾经接手过一个历史项目,里面INFO字段的DP被声明为Float,但实际数据里写的是Integer,解析直接崩了。所以,元数据就是契约,别自己破坏它。
1.4 INFO与FORMAT的区别与结构
这个问题我每次讲课都会被问到。INFO和FORMAT都是一个键值对字符串,但作用域完全不同:
- INFO:作用于整个位点(一行就一个值),比如覆盖深度、变异类型
- FORMAT:作用于每个样本的单个基因型,比如GT、AD、PL
拿之前那个例子来说:INFO=DP=120表示这个位点的总覆盖深度是120,无论有多少样本,这个值都是一个。而FORMAT=GT对应样本列0/1,表示该样本在这个位点是杂合子。
为什么不能把样本级别的深度也放进INFO?你想想看,如果我有100个样本,每个样本的深度都不一样,放在INFO里就得写100个键,那得多乱。FORMAT就是为了这种样本级别的结构化数据而设计的。
1.5 常用格式规范小结
聊完结构,我把自己常用的几条规范清单列出来。这些规矩不遵守,工具就报错;遵守了,大家数据交换时也省心。
| 规范项 | 具体要求 |
|---|---|
| 字段分隔符 | 使用制表符,不能混用空格 |
| 缺失值 | 用.占位,不要留空 |
| 字符串编码 | 统一用UTF-8,无BOM |
| 换行符 | Unix风格(LF),不要用CRLF |
| 压缩方式 | 推荐使用bgzip压缩,配合tabix建立索引 |
关键警告:别用普通gzip压缩VCF!普通gzip不支持随机访问,而bgzip压缩的文件可以配合tabix快速索引和区域查询。我刚开始学的时候,把上百G的VCF用gzip压了,结果每次想查一个区域都要解压整个文件,白白浪费了几个小时。bgzip是标配,没有商量余地。
最后,我把本章的知识体系用一张图串起来,方便你了解VCF的全局结构:
一点小建议:学VCF格式最好的方法就是打开一个真实的VCF文件看。你可以用less或者head -n 20预览,看清每一行的结构。我自己的习惯是,拿到一个新VCF文件,先看元数据里INFO和FORMAT的定义,再看数据行的实际内容,这样心里就有数了。