This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Splitting vcf files to individual samples

Hi everyone. I have a vcf file ( .vcf.gz format) containing variants for multiple samples and I would like to split them to individual vcf files so that each file contains variants from one sample only. Does anyone have an easy, quick, reliable way for doing this? Thanks

vcf

5 answers

already stated here and here:

for file in *.vcf*; do
  for sample in `bcftools query -l $file`; do
    bcftools view -c1 -Oz -s $sample -o ${file/.vcf*/.$sample.vcf.gz} $file
  done
done

Why did I break it down.All the 0/0 columns are automatically eliminated, right?I'm just left with 0/1 and 1/1

Exactly. If you divide a multisample file you'll find variants that appeared in other samples but not in a particular one, therefore you may be interested in private variants only. This code does indeed remove all other samples' variants that would be 0/0 in individual samples.

Excuse me, if I want to get the whole data after splitting, how should I adjust this code?

Just remove the -c1 option, which stands for "1 minimum non-reference allele".

Thank you very much.However, I have one more question.Splitting by sample is equivalent to splitting by column.If I have too much data on a chromosome site, I want to break it down into several groups for training.How should the code be adjusted?

The for sample loop forces the file to be divided in all individual samples present in the file. If you have a list of samples you'd like to restrict the output to, then you only have to modify that loop, such as

for sample in sample1 sample2 sample3; do

or as

for sample in $(cat list_of_samples.txt); do

or, if you want to generate a new multsample vcf with just a few samples in it, you can remove the for sample loop completely and use a single bcftools command

bcftools view -S list_of_samples.txt -Oz -o subset.vcf.gz large.vcf.gz

Might be a better way for this, but the following for loop should work:

for sample in `bcftools query -l yourfile.vcf`
do
java -jar GenomeAnalysisTK.jar -T SelectVariants -R reference.fasta -V yourfile.vcf -o ${sample}.vcf -sn $sample -env ef
done

Or with vcftools

for sample in `bcftools query -l yourfile.vcf`
do
vcf-subset --exclude-ref -c $sample yourfile.vcf > ${sample}.vcf
done

Alternatively, using gnu-parallel

bcftools query -l yourfile.vcf | parallel -j 8 'java -jar GenomeAnalysisTK.jar -T SelectVariants -R reference.fasta -V yourfile.vcf -o {}.vcf -sn {} -env ef'

or with vcftools

bcftools query -l yourfile.vcf | parallel -j 8 'vcf-subset --exclude-ref -c {} yourfile.vcf > {}.vcf'

with 8 the number of processes run in parallel, to be adapted to your system.

vcftools

vcf-subset --exclude-ref -c sample1 in.vcf > out.vcf

vcf-subset --exclude-ref -c sample1,sample2 in.vcf > out.vcf

Thanks. I tried this but got this error message: "Can't locate Vcf.pm @INC" Any idea how to get round this?

It means that the tool can't find a perl module. You'll have to install it, but my knowledge of perl is quite limited. Someone else can probably help you better with that, or you can have a look at an alternative (GATK) solution in my post.

You run the following line or add it to .bashrc and then source .bashrc:

export PERL5LIB=/path/to/installation_dir/vcftools_0.1.13/perl/

Both commands worked perfectly! Thanks!

I wrote one for Individual VCF files from main VCF file

$   curl -sL "https://raw.githubusercontent.com/arq5x/bedtools2/bc2f97d565c36a82c1a0b12f570fed4398001e5f/test/map/test.vcf" |\
    java -jar dist/biostar130456.jar -x -z -p "sample.__SAMPLE__.vcf.gz" 
sample.NA00003.vcf.gz
sample.NA00001.vcf.gz
sample.NA00002.vcf.gz

Check out these posts : Splitting A Vcf File

Split a VCF file into individual sample files

Log in to answer this question.