重复一篇文献的GWAS(一):基因型数据整理
文献:A new regulator of seed size control in Arabidopsis identified by a genome-wide association study
数据来源:1001 Genomes Project website
http://1001genomes.org/data/GMI-MPI/releases/v3.1/
1. 下载原始vcf文件
因为不确定这篇文献用的哪一个群体vcf文件,所以两个都下载了,想查看vcf的维度,查看多少列好说,但是用命令行提取第一列想看看有多少个SNP时,遇到了很大困难,太慢了。
18G Sep 25 2015 1001genomes_snp-short-indel_only_ACGTN.vcf.gz
133G Sep 26 2015 1001genomes_snp-short-indel_with_tair10_only_ACGTN.vcf.gz
这两个vcf文件的列是一样的,都是1135个样本。行的话,第2个文件包含基因组的每一个位置(包括没有测到以及没有多态性的点),所以文件很大。据此应该可以确定,第一个才是需要用到的vcf文件。只保留snp的记录,并根据这篇文献用到的样本提取列就可以了。
认识一种新格式:hdf5
除了上面两个群体vcf文件,还能找到下面这个snp矩阵文件,采用一种hdf5的格式存储,这种格式专门用来存储大数据,在Python中有专门的工具来读取,速度挺快。里面存储的snp都是过滤掉triallelic的。
877M Dec 5 2014 imputed_snps_binary.hdf5
$ ~/miniconda3/bin/python3.6
>>> import h5py
>>> import os
>>> import numpy as np
>>> file_name = 'imputed_snps_binary.hdf5'
>>> f = h5py.File(file_name, 'r')
>>> f.keys()
<KeysViewHDF5 ['accessions', 'positions', 'snps']>
>>> a=f['accessions'][:]
>>> b=f['positions'][:]
>>> c=f['snps'][:]
>>> a
array([b'88', b'108', b'139', ..., b'19949', b'19950', b'19951'],
dtype='|S5')
>>> len(a)
1135
>>> b
array([ 55, 56, 63, ..., 26975445, 26975448, 26975450],
dtype=int32)
>>> len(b)
10709949
>>> c
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=int8)
>>> c.shape
(10709949, 1135)
根据最后一行可知:10.7M的snp。
2. 根据样本提取vcf
根据文献补充材料提供的样本编号提取,用到的是vcftools,之前总结过vcftools过滤的用法。
从整理的结果来看,在191个样本中19个样本是没有GWAS ID
的,这部分是怎么回事呢?在1001 Genomes Project项目官网提供的1135个accessions的详细信息中,也没有找到这19个accession的记录。难道这19个是作者自己测的重测序数据吗?
只能先用172个样本的了,这是我的过滤命令
nohup vcftools --gzvcf 1001genomes_snp-short-indel_only_ACGTN.vcf.gz \
--remove-indels --min-alleles 2 --max-alleles 2 \
--recode --keep sample.list --out 172sample &
After filtering, kept 172 out of 1135 Individuals
Outputting VCF file...
After filtering, kept 10707430 out of a possible 12883854 Sites
Run Time = 6859.00 seconds
10.7M的snp,注意:在提取172样本之后,这10.7M记录里面可能还有些是在172个样本中没有出现的,要过滤掉。
是这样吗?统计一下就知道了。
nohup vcftools --vcf 172sample.recode.vcf --freq --out freq &
$ lsx freq.frq | head -n 5
CHROM POS N_ALLELES N_CHR {ALLELE:FREQ}
1 55 2 158 C:1 T:0
1 56 2 166 T:1 A:0
1 63 2 138 T:0.971014 C:0.0289855
1 73 2 146 C:0.945205 A:0.0547945
#看看第四列出现了多少个0,此时5,6列变为-nan,共8943行
#(这里我试了一下nohup vcftools --vcf 172sample.recode.vcf --maf 0 --max-maf 1 --recode --out 172sample.1 看能不能过滤掉-nan的情况,结论是不能)
第五列、第六列出现了基因频率是1、0的情况,是说群体中该位点全部都是ALT,这可能是参考基因组组装错了,也可能是被选来做组装的那个样本在该位点存在SNP,这也要过滤掉。这两处的过滤可以放在MAF那一步过滤,现在先放着。
3. 填充
现在看一下文献是怎么做的。
nohup java -Xss5m -Xmn25G -Xms100G -Xmx100G -jar \
~/mysoft/beagle/beagle.12Jul19.0df.jar nthreads=2 \
gt=172sample.recode.vcf out=172sample_out ne=172 &
#可能会遇到内存溢出的报错
这一步用时很长,14.5小时,没有过滤,全部填充了,10707430个SNP。
4. 根据MAF过滤
再来根据MAF过滤。
nohup vcftools --gzvcf 172sample_out.vcf.gz --maf 0.05 \
--recode --out 172sample_maf_filter &
提出一个疑问,在查看vcf文件时,看到了0|0,1|1这两种基因型,但是没有看到0|1这种基因型。我在想是不是1001 Genomes Project这个项目只区分有/无这个变异,而不区分纯合/杂合变异,或者是这些样本足够纯合。
$ lsx 172sample_maf_filter.recode.vcf | grep "^#" -v | wc -l
1656967
1.66M的SNP。和文献中有差异,应该是那19个样本没有参与进来导致的。
剧透
:下文两个文件要用到SNP的ID,因为最原始的vcf文件第三列没有ID,我只能自己加了。
$ lsx 172sample_maf_filter.recode.vcf | head -n 10 > header
$ lsx 172sample_maf_filter.recode.vcf | grep "^#" -v | awk '{$3=$1"_"$2;print $0}' | sed 's/ /\t/g' > body &
$ cat header body > 172sample_maf_filter_snpID.vcf &
5. 接下来是基于连锁不平衡/LD的过滤
Linkage disequilibrium based SNP pruning
在这一步之后,剩下的SNP彼此之间可以看作是连锁平衡的,这样就能减少曼哈顿图中“冒出”一串点的情况。
参考:
https://www.jianshu.com/p/57c2dbda8a86
http://zzz.bwh.harvard.edu/plink/summary.shtml#prune
第1步:将vcf转成ped
老版本的PLINK不能将vcf格式转为ped(plink 2009, vcf 2010),这一步就用PLINK 1.9吧
nohup plink --vcf 172sample_maf_filter_snpID.vcf --recode --out 172sample &
# 生成
# 172sample.log 172sample.map 172sample.ped 172sample.nosex
# map和ped是主要结果,这两种格式比较重要,可以了解一下
第2步:生成list
nohup ~/mysoft/plink-1.07-x86_64/plink --file 172sample --indep 50 5 2 &
# 生成
# plink.prune.in plink.prune.out
# Each is a simlpe list of SNP IDs; both these files can subsequently be specified as the argument for a --extract or --exclude command.
vcf文件里面如果没有SNP ID,得到的这两个文件里面每一行都只有一个点“.”。
第3步:根据list提取SNP
$ head -n 4 plink.prune.in
1_63
1_92
1_138
1_266
$ lsx plink.prune.in | wc -l
335565
$ nohup ~/mysoft/plink-1.07-x86_64/plink --file 172sample \
--extract plink.prune.in --recode --out 172sample_maf_filter_snpID_LD_filter &
335.6K的SNP,和原文献很接近了,
到这一步基因型数据算是整理完了。