关于SNP的过滤(1):如何使用vcftools进行SNP过滤

前言

很多关注我这个专题的朋友都在后台留言,说想了解更多关于SNP过滤的东西。是的,确实这是一个比较重要的问题。第一,过滤到一些低质量的SNP可以防止calling一些假阳性的SNP,这些假阳性的SNP会很大程度影响到后续的一系列的分析,例如GWAS等的分析,最后影响相关生物学问题的解答。第二,如果你有很多的个体,往往你的call完SNP后,VCF文件的大小的会比较大,如果不经过过滤,对下游的群体结构分析,PCA等相关的计算,都会对计算机产生巨大的负担(运行速度还有需要的内存等)。讲了那么多,在接下来几周会从简单开始,讨论学习一下SNP的过滤的流程,常用工具,还有通常推荐使用的一些参数。

文章主要是根据网上SNP Filtering Tutorial的课程总结翻译而成,推荐新手跟着一步一步来操作,进而理解掌握。老司机就自行忽略看看就好了。

预备工作

创建文件夹,下载测试数据包,解压文件

mkdir filtering
cd filtering
curl -L -o data.zip https://www.dropbox.com/sh/bf9jxviaoq57s5v/AAD2Kv5SPpHlZ7LC7sBz4va8a?dl=1
unzip data.zip 
ls -thrl 

看看数据包里包含了什么文件

total 73742
-rwxr--r-- 1 hhu pawsey0149   109633 Mar  6  2015 BR_004-RG.bam
-rwxr--r-- 1 hhu pawsey0149   247496 Mar  6  2015 BR_004-RG.bam.bai
-rwxr--r-- 1 hhu pawsey0149   120045 Mar  6  2015 BR_006-RG.bam
-rwxr--r-- 1 hhu pawsey0149   247712 Mar  6  2015 BR_006-RG.bam.bai
drwxr-s--- 2 hhu pawsey0149     4096 Jul  1 14:54 __MACOSX
-rwxr--r-- 1 hhu pawsey0149      399 Mar  6  2015 popmap
-rwxr--r-- 1 hhu pawsey0149 68264393 Mar  6  2015 raw.vcf.gz
-rwxr--r-- 1 hhu pawsey0149  6804314 Mar  6  2015 reference.fasta
-rwxr--r-- 1 hhu pawsey0149  1085387 Mar  6  2015 reference.fasta.amb
-rwxr--r-- 1 hhu pawsey0149  1068884 Mar  6  2015 reference.fasta.ann
-rwxr--r-- 1 hhu pawsey0149  6379720 Mar  6  2015 reference.fasta.bwt
-rwxr--r-- 1 hhu pawsey0149   353544 Mar  6  2015 reference.fasta.clstr
-rwxr--r-- 1 hhu pawsey0149   976388 Mar  6  2015 reference.fasta.fai
-rwxr--r-- 1 hhu pawsey0149  1594913 Mar  6  2015 reference.fasta.pac
-rwxr--r-- 1 hhu pawsey0149  3189872 Mar  6  2015 reference.fasta.sa
-rwxr--r-- 1 hhu pawsey0149   137209 Mar  6  2015 stats.out

下载并且安装VCFTOOLS

git clone https://github.com/vcftools/vcftools.git
cd vcftools
./autogen.sh
./configure
make
make install

该文章也会用到一个叫做mawk的软件,它其实就是更加简单版的awk,也需要下载,我这里偷懒用conda下载,其实上面的vcftools 也可以用conda下载

conda install mawk

小试牛刀

首先做一个过滤,
我们将只保留已那些变异,至少50%的个体成功被snp calling的位点,最低质量分数为30的位点,次要等位基因计数为3的位点。

vcftools --gzvcf raw.vcf.gz --max-missing 0.5 --mac 3 --minQ 30 --recode --recode-INFO-all --out raw.g5mac3

解读一下这个代码做了什么:
在这段代码中,我们调用vcftools,在--vcf标志后给它一个vcf文件, - max-missing 0.5告诉它过滤低于50%的基因型(跨所有个体)--mac 3标志告诉它过滤次要等位基因计数小于3的SNP。
这与基因型有关,因此必须在至少1个纯合子和1个杂合子或3个杂合子中的变异调用。 --recode标志告诉程序使用过滤器写入一个新的vcf文件,--recode-INFO-all保留旧vcf文件中的所有INFO标志。--out 输出的文件名称

运行完后,在屏幕或者生成的log file中会有这样的信息:

After filtering, kept 40 out of 40 Individuals
Outputting VCF file...
After filtering, kept 78434 out of a possible 147540 Sites
Run Time = 17.00 seconds

这个output给了你一些基本的信息,这里你所用到的40个个体,全部被保留下来,然后147540中的78434个变异位点经过过滤后被保留下来(几乎一半的变异位点被过滤掉)。运行时间:17秒。

在得到这个过滤完的文件后,继续进一步过滤:

我们接下来过滤的标准是基因型调用的最小深度和最小平均深度。

vcftools --vcf raw.g5mac3.recode.vcf --minDP 3 --recode --recode-INFO-all --out raw.g5mac3dp3 

运行完的log file 结果如下:

After filtering, kept 40 out of 40 Individuals
Outputting VCF file...
After filtering, kept 78434 out of a possible 78434 Sites
Run Time = 14.00 seconds

可以惊讶的发现,所有的位点都被保留了下来。这说明,上述第一步得到的过滤的文件中的所有位点,已经满足了最小深度至少大于3的过滤条件。

在这里你可能会提出疑问,最小深度大于3这个条件是否足够严谨filter出置信的SNP (理论上是越高越好,但是过高也不太好,这个内容会再以后的文章再具体讨论)。简短的回答是像FreeBayes和GATK这样复杂的多样本SNP calling的工具可以自信地调用几乎没有读数的基因型,因为所有样本的变异是同时评估预测的。因此,这里的过滤是基于来自所有个体的所有读数的三个reads和还有其他的先验信息。但是,我们还会做很多其他的过滤步骤!

如果你还是担心深度不够的影响,我们也可以测测低深度可能产生的SNP错误率。

下载好写好的脚本

curl -L -O https://github.com/jpuritz/dDocent/raw/master/scripts/ErrorCount.sh
chmod +x ErrorCount.sh 
./ErrorCount.sh raw.g5mac3dp3.recode.vcf 

该脚本计算由于低读取深度而导致的潜在基因分型错误的数量,它会报告基于观察杂合子中第二等位基因的50%二项概率和基于25%概率的高范围。

运行结果

Potential genotyping errors from genotypes from only 1 read range from 0 to 0.0
Potential genotyping errors from genotypes from only 2 reads range from 0 to 0.0
Potential genotyping errors from genotypes from only 3 reads range from 15986 to 53714.22
Potential genotyping errors from genotypes from only 4 reads range from 6230 to 31502.04
Potential genotyping errors from genotypes from only 5 reads range from 2493 to 18914
40 number of individuals and 78434 equals 3137360 total genotypes
Total genotypes not counting missing data 2380094
Total potential error rate is between 0.0103815227466 and 0.0437504821238
SCORCHED EARTH SCENARIO
WHAT IF ALL LOW DEPTH HOMOZYGOTE GENOTYPES ARE ERRORS?????
The total SCORCHED EARTH error rate is 0.129149100834.

现在,由于基因型少于5的深度,VCF文件的最大错误率小于5%。看,没什么好担心的。

下一步,我们可以去除那些没有被测序的很好的个体,我们可以通过估计个体间数据丢失的水平来过滤。

vcftools --vcf raw.g5mac3dp3.recode.vcf --missing-indv

这会生成一个out.imiss的文件,看看他里面是什么:

cat out.imiss

INDV    N_DATA  N_GENOTYPES_FILTERED    N_MISS  F_MISS
BR_002  78434   0   13063   0.166548
BR_004  78434   0   16084   0.205064
BR_006  78434   0   25029   0.319109
BR_009  78434   0   30481   0.38862
BR_013  78434   0   69317   0.883762
BR_015  78434   0   8861    0.112974
BR_016  78434   0   29789   0.379797
BR_021  78434   0   17422   0.222123
BR_023  78434   0   43913   0.559872
BR_024  78434   0   24220   0.308795
BR_025  78434   0   21998   0.280465
BR_028  78434   0   26786   0.34151
BR_030  78434   0   74724   0.952699
BR_031  78434   0   26488   0.337711
BR_040  78434   0   19492   0.248515
BR_041  78434   0   17107   0.218107
BR_043  78434   0   16384   0.208889
BR_046  78434   0   28770   0.366805
BR_047  78434   0   13258   0.169034
BR_048  78434   0   24505   0.312428
WL_031  78434   0   22566   0.287707
WL_032  78434   0   22604   0.288191
WL_054  78434   0   32902   0.419486
WL_056  78434   0   34106   0.434837
WL_057  78434   0   37556   0.478823
WL_058  78434   0   31448   0.400949
WL_061  78434   0   35671   0.45479
WL_064  78434   0   47816   0.609634
WL_066  78434   0   10062   0.128286
WL_067  78434   0   47940   0.611215
WL_069  78434   0   38260   0.487799
WL_070  78434   0   21188   0.270138
WL_071  78434   0   16692   0.212816
WL_072  78434   0   46347   0.590904
WL_076  78434   0   78178   0.996736
WL_077  78434   0   55193   0.703687
WL_078  78434   0   54400   0.693577
WL_079  78434   0   19457   0.248068
WL_080  78434   0   30076   0.383456
WL_081  78434   0   30334   0.386746

您可以看到有些人的数据丢失率高达99.6%。我们绝对想要过滤掉这些。现在我们需要创建一个缺失数据超过50%的个体的列表。

mawk '$5 > 0.5' out.imiss | cut -f1 > lowDP.indv

现在我们有一个要删除的个体列表,我们可以直接将其提供给VCFtools进行过滤。

vcftools --vcf raw.g5mac3dp3.recode.vcf --remove lowDP.indv --recode --recode-INFO-all --out raw.g5mac3dplm

然后该文章的原作者非常贴心的,

我们可以将变异限制为在高百分比的个体中,并通过基因型的平均深度进行过滤。

vcftools --vcf raw.g5mac3dplm.recode.vcf --max-missing 0.95 --maf 0.05 --recode --recode-INFO-all --out DP3g95maf05 --min-meanDP 20

这对所有个体应用的calling rate 为(95%)。这对群体是采集自两个地方的变异来说是已足够。但是当你有多个采样地点时,你还希望按个体特定的calling rate进行过滤。 VCFtools不会直接计算,但这是一个简单的解决方法。首先,我们需要一个文件来定义地点(个体)。大多数程序希望文件具有两个制表符分隔列。首先是样本名称,第二个是个体的群体类型分配。

cat popmap

BR_002  BR
BR_004  BR
BR_006  BR
BR_009  BR
BR_013  BR
BR_015  BR
BR_016  BR
BR_021  BR
BR_023  BR
BR_024  BR
BR_025  BR
BR_028  BR
BR_030  BR
BR_031  BR
BR_040  BR
BR_041  BR
BR_043  BR
BR_046  BR
BR_047  BR
BR_048  BR
WL_031  WL
WL_032  WL
WL_054  WL
WL_056  WL
WL_057  WL
WL_058  WL
WL_061  WL
WL_064  WL
WL_066  WL
WL_067  WL
WL_069  WL
WL_070  WL
WL_071  WL
WL_072  WL
WL_076  WL
WL_077  WL
WL_078  WL
WL_079  WL
WL_080  WL
WL_081  WL

现在我们需要创建两个列表,这些列表只包含每个个体的个别名称。

mawk '$2 == "BR"' popmap > 1.keep && mawk '$2 == "WL"' popmap > 2.keep

接下来,我们使用VCFtools来估计每个群体中基因座的缺失数据。

vcftools --vcf DP3g95maf05.recode.vcf --keep 1.keep --missing-site --out 1
vcftools --vcf DP3g95maf05.recode.vcf --keep 2.keep --missing-site --out 2 

这会生成两个文件分别是 1.lmiss 和2.lmiss

快速看看文件里面的内容:

head -3 1.lmiss

CHR     POS     N_DATA  N_GENOTYPE_FILTERED     N_MISS  F_MISS
E1_L101 9       34      0                       0       0
E1_L101 15      34      0                       0       0

这里文章的原作者在第一行加了header 让你更容易去理解每一列。但我们感兴趣的是最后一列是该基因座缺失数据的百分比。我们可以合并这两个文件,并制作一个关于要删除的10%缺失数据阈值的基因座列表。请注意,这是丢失数据总体速率的两倍。

cat 1.lmiss 2.lmiss | mawk '!/CHR/' | mawk '$6 > 0.1' | cut -f1,2 >> badloci

然后,我们将此文件反馈到VCFtools以删除任何基因座。

vcftools --vcf DP3g95maf05.recode.vcf --exclude-positions badloci --recode --recode-INFO-all --out DP3g95p5maf05

同样,我们只有两个个体,所以我们的过滤可以过滤这些。然而,在多地点采样的研究就不能像这样处理了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,406评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,976评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,302评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,366评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,372评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,457评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,872评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,521评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,717评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,523评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,590评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,299评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,859评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,883评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,127评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,760评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,290评论 2 342

推荐阅读更多精彩内容