4、输入文件格式:VCF格式与转换归纳总结
4.1 为什么非得是VCF?
你想想看,做变异检测的,不管是WGS、WES还是靶向测序,最后交出来的报告,十有八九都是VCF格式。VCF全称是Variant Call Format,说白了,它就是变异检测领域的“通用语言”。
我个人习惯,拿到一个VCF文件,第一件事不是急着跑ANNOVAR,而是先看一眼它的元数据部分,也就是以“#”开头的行。这就好比读一本书,先翻翻目录和前言,心里大概有个底。
convert2annovar.pl脚本做一步式转换。
4.2 VCF文件的结构长什么样?
一个标准的VCF文件,结构很清晰。我把它拆成三部分来讲:
- 元数据行: 以
##开头,描述文件格式、版本、样本信息、过滤条件等。这部分是给程序看的,也是给有经验的人看的。 - 标题行: 只有一行,以
#CHROM开头,定义了后面数据列的标题。 - 数据行: 每一行代表一个变异位点的信息,各列由制表符(Tab)分隔。
一个典型的数据行有8个核心列,再加上样本列。核心8列如下:
| 列号 | 名称 | 说明 |
|---|---|---|
| 1 | CHROM | 染色体名称,例如 chr1 或 1 |
| 2 | POS | 变异在染色体上的起点位置(1-based) |
| 3 | ID | dbSNP的rs号,如果没有则为 . |
| 4 | REF | 参考等位基因 |
| 5 | ALT | 替代等位基因。如果是SNP,就是单碱基;如果是Indel,可能是 ATG 这样的序列。 |
| 6 | QUAL | 变异质量值。Phred-scale质量得分,值越高,变异越可信。 |
| 7 | FILTER | 过滤状态。PASS表示通过所有过滤,否则是具体的过滤标签。 |
| 8 | INFO | 额外的变异信息,用键值对表示,例如 DP=100;AF=0.5 |
我自己在项目中经常遇到一个问题:染色体前缀。有的VCF用 chr1,有的用 1。ANNOVAR默认识别不带“chr”前缀的染色体名。所以你在转换前,需要确认这一点。如果你的VCF里是 chr1,我建议你用sed或awk先把“chr”去掉。
为什么会这样?因为ANNOVAR内部的参考基因组文件(如hg19、hg38)的染色体名字,默认是不带“chr”的。
4.3 INFO字段的解析,这里有个坑
VCF文件的INFO列,内容丰富,但也是“重灾区”。最常见的几个INFO条目如下:
DP:测序深度,在这个位点上覆盖到的reads总数。AF:等位基因频率,ALT等位基因在样本中的频率。AC:ALT等位基因的计数。AN:总的等位基因数。MQ:Mapping Quality的均值。
我个人习惯,在INFO列里,特别关注 DP 和 AF 这两个值。特别是当你做过滤的时候,比如你要丢掉深度低于20x的位点,在转换成avinput之前,最好提前处理掉,否则ANNOVAR不会帮你做这件事。
convert2annovar.pl 脚本,默认是“无脑”读取VCF的CHROM、POS、REF、ALT列,然后生成avinput。它不会替你处理INFO里的过滤条件。所以,先过滤,再转换,这是个好习惯。
我遇到过最头疼的事情是什么?
曾经有一个合作者给我的VCF,居然在同一行里,ALT列用逗号隔开了多个等位基因,比如 A,G。这种多等位基因位点,ANNOVAR处理起来会出错,因为它的格式默认每一行只记录一个变异等位基因对。
4.4 转换工具:一招鲜,吃遍天?
把VCF转换成ANNOVAR能吃的avinput格式,主要有两种方式。我最常用的是第一种。
方法一:使用 convert2annovar.pl(推荐)
这是ANNOVAR自带的小工具,用法很简单:
perl convert2annovar.pl -format vcf4 example.vcf > example.avinput
-format vcf4 告诉它输入格式是VCF 4.x版本。这个命令会帮你完成格式转换,同时丢掉一些ANNOVAR不关心的列。
如果你想保留样本的基因型信息(比如用于后续的过滤),可以加上 -includeinfo 参数:
perl convert2annovar.pl -format vcf4 -includeinfo example.vcf > example_withinfo.avinput
方法二:手动编写脚本(自己动手,丰衣足食)
有时候,VCF文件太大,或者包含一些特殊的信息,你需要自己写一个脚本来完成转换。其实,avinput的格式很简单:它是制表符分隔的文本文件,每行包含6个列:
chr pos ref alt (funcref) (exonref)
chr:染色体名pos:起始位置ref:参考等位基因alt:替代等位基因funcref:通常是空格,保留给注释器使用exonref:同上,保留用
手动转换的思路,就是从VCF的CHROM、POS、REF、ALT列分别取出来,然后按制表符拼接。我写过最简短的awk脚本:
awk 'BEGIN{OFS="\t"} !/^#/ {print $1, $2, $4, $5, ".", "."}' example.vcf > example.avinput
这个脚本跳过所有注释行(以#开头的行),然后提取第1、2、4、5列,最后补两列“.”。
4.5 文件转换流程图
下面这张图,总结了我上面讲的核心流程。从VCF原始文件开始,经过一次简单的格式转换,最终成为ANNOVAR能够理解的输入。
convert2annovar.pl,而是用管道的方式,一边解压,一边转换,一边注释。比如:
zcat huge.vcf.gz | perl convert2annovar.pl -format vcf4 -includeinfo - > huge.avinput
这个“-”告诉程序从标准输入读取。这样能节省大量磁盘IO和临时空间。
4.6 常见问题:我的VCF为什么转不了?
我把自己踩过的坑,总结成了一张表,你对照着看,能省不少时间。
| 问题 | 现象 | 解决方法 |
|---|---|---|
| 染色体名不统一 | 转换后avinput中的 chr1 导致后续注释找不到位置 |
用 sed 's/^chr//' 去除“chr”前缀 |
| 多等位基因位点 | ALT列为 A,G,转换后变成一行,但ANNOVAR只认一对一的变异 |
使用 bcftools norm -m -any 将其拆分成单等位基因 |
| 染色体顺序错误 | avinput中染色体顺序乱了,导致后期合并结果混乱 | 按照染色体自然顺序排序,可以用 sort -k1,1 -k2,2n |
| 参考基因组版本不匹配 | 注释结果全部为NA | 确认VCF是hg19还是hg38,并下载对应版本的ANNOVAR数据库 |
4.7 总结:记住这几个关键点
- VCF格式是标准输入,但不能直接喂给ANNOVAR。
- 转换的核心是提取
CHROM, POS, REF, ALT四列。 convert2annovar.pl是官方推荐的转换工具。- 转换前,一定要做过滤和格式清洗。
- 遇到多等位基因,先用
bcftools norm或vt decompose拆分。
我以前有一次,因为没注意染色体前缀的问题,导致整个批次的样本注释结果全错了,白白浪费了三天时间。所以你想想看,花5分钟检查一下VCF文件,能把后面可能出的问题扼杀在摇篮里。