<p>Found a great tool with <a href="http://snpeff.sourceforge.net/SnpSift.html#filter" rel="nofollow noreferrer">SnpSift</a>!</p>

<p>From the examples: I want to keep samples where the genotype for the first sample is homozygous variant and the genotype for the second sample is reference:</p>

<pre><code>cat variants.vcf | java -jar SnpSift.jar filter "isHom( GEN[0] ) &amp; isVariant( GEN[0] ) &amp; isRef( GEN[1] )" &gt; filtered.vcf 
</code></pre>

CC BY-SA 4.0
2018-11-27T01:20:35.917Z
2018-11-27T10:23:26.713Z
2018-11-27T10:23:26.713Z
Joanne
<p>Given an input file <code>input.vcf</code>, I would take this approach:</p>

<ol>
<li>Create two text files: one with the male sample names (<code>males.txt</code>) and one with the female sample names (<code>females.txt</code>) (one sample per line)</li>
<li><p>Create a BCF (for speed) for all the samples in each list while dropping the <code>INFO</code> field so that <code>INFO/AC</code> is recalculated (I'm not sure dropping the <code>INFO</code> field is strictly necessary). Then only keep sites with a minor allele count greater than zero:</p>

<pre><code>bcftools view --samples-file males.txt input.vcf -Ou | bcftools annotate -x INFO  -Ou | bcftools view --min-ac 1:minor -Ob -o male_variants.bcf
bcftools view --samples-file females.txt input.vcf -Ou | bcftools annotate -x INFO -Ou | bcftools view --min-ac 1:minor -Ob -o female_variants.bcf
</code></pre></li>
<li><p>Use <code>isec</code> to create intersects and complements of the two variant files and store them in <code>dir/*</code>:</p>

<pre><code>bcftools isec male_variants.bcf female_variants.bcf -p dir -Oz
</code></pre></li>
</ol>

<p>Double-check <code>dir/README.txt</code>, but the files you seek should be named <code>dir/0000.vcf.gz</code> and <code>dir/0001.vcf.gz</code></p>

<p><strong>Disclaimer:</strong> This code is untested.</p>

CC BY-SA 4.0
2018-11-27T19:08:30.383Z
2018-11-27T19:14:52.267Z
2018-11-27T19:14:52.267Z
winni2k
<p>if you could provide seperate list of male and female samples names you can something like this:</p>

<pre><code>$ bcftools view -e 'GT[@males.txt]!="0/1" &amp;&amp; GT[@females.txt]!="0/0"' combined.vcf.gz
</code></pre>

<p>or if you don't want to take care of the exact genotype you can write it more generic:</p>

<pre><code>$ bcftools view -e 'GT[@males.txt]!="alt" &amp;&amp; GT[@females.txt]!="ref"' combined.vcf.gz
</code></pre>

<p>fin swimmer</p>

CC BY-SA 4.0
2018-11-27T05:30:00.300Z
2018-11-27T05:57:03.123Z
2018-11-27T05:57:03.123Z
finswimmer
<p>using vcffilterjdk  <a href="http://lindenb.github.io/jvarkit/VcfFilterJdk.html" rel="nofollow noreferrer">http://lindenb.github.io/jvarkit/VcfFilterJdk.html</a></p>

<blockquote>
  <p>or ask for all individuals named *.M and *.F.</p>
</blockquote>

<pre><code>java -jar dist/vcffilterjdk.jar -e 'return variant.getGenotypes().stream().allMatch(G-&gt;(G.getSampleName().endsWith("M") &amp;&amp; G.isHet()) || (G.getSampleName().endsWith("F") &amp;&amp; G.isHomRef())); ' input.vcf
</code></pre>

<p><code>variant.getGenotypes().stream()</code> get a stream of genotypes 'G' for the current variant.  </p>

<p><code>allMatch</code> all genotypes must match the statements below:</p>

<p><code>G.getSampleName().endsWith("M") &amp;&amp; G.isHet()</code> sample 's name ends with 'M' and is heterozygous</p>

<p>OR</p>

<p><code>G.getSampleName().endsWith("F") &amp;&amp; G.isHet()</code> sample 's name ends with 'F' and is Hom-ref</p>

CC BY-SA 4.0
2018-11-28T08:14:06.293Z
2018-11-28T08:14:06.293Z
Pierre
<p>I have a single VCF file of variants for a population that includes males &amp; females and I would like to pull out all variants that are sex-specific. For example, sites where all males are 0/1 and all females are 0/0. Is there a way to do this using bcftools or vcftools? I could enumerate each individual name, or ask for all individuals named *.M and *.F.</p>

<p>I first tried running smoove on the male and female populations separately then comparing the two VCFs, but I'm working with a draft genome with loads of contigs. As only contigs containing variants are output in each VCF, and these are different between the two files, vcftools couldn't handle the comparison. </p>

<p>Someone here <a href="https://github.com/samtools/bcftools/issues/118" rel="nofollow noreferrer">https://github.com/samtools/bcftools/issues/118</a> managed to get it working ike this: </p>

<pre><code>$bcftools view -f PASS -i 'GT~"0/0.*0/1.*0/1.*0/1.*0/1"' combined.vcf.gz
</code></pre>

<p>but the same syntax gives me no variants (yet I can see some that meet my criteria in IGV).</p>

CC BY-SA 4.0
2018-11-27T19:13:31.057Z
Do you only want sites where either all males or all females are heterozygotes? Or do you also want sites that are more generally polymorphic in males or females but not the other?
winni2k
<vcf>
how to filter a multi-VCF for sex-specific genotypes?
# how to filter a multi-VCF for sex-specific genotypes?

(Asked by: username_0 on 2018-11-26)

I have a single VCF file of variants for a population that includes males & females and I would like to pull out all variants that are sex-specific. For example, sites where all males are 0/1 and all females are 0/0. Is there a way to do this using bcftools or vcftools? I could enumerate each individual name, or ask for all individuals named *.M and *.F.
I first tried running smoove on the male and female populations separately then comparing the two VCFs, but I'm working with a draft genome with loads of contigs. As only contigs containing variants are output in each VCF, and these are different between the two files, vcftools couldn't handle the comparison. 
Someone here https://github.com/samtools/bcftools/issues/118 managed to get it working ike this: 
$bcftools view -f PASS -i 'GT~"0/0.*0/1.*0/1.*0/1.*0/1"' combined.vcf.gz

but the same syntax gives me no variants (yet I can see some that meet my criteria in IGV).

**Tags:** vcf
> **Comments:**
> **username_1**: Do you only want sites where either all males or all females are heterozygotes? Or do you also want sites that are more generally polymorphic in males or females but not the other?  

---

## 4 answers

### Answer by username_0 on 2018-11-27. Score: 2

Found a great tool with SnpSift!
From the examples: I want to keep samples where the genotype for the first sample is homozygous variant and the genotype for the second sample is reference:
cat variants.vcf | java -jar SnpSift.jar filter "isHom( GEN[0] ) & isVariant( GEN[0] ) & isRef( GEN[1] )" > filtered.vcf


---

### Answer by username_1 on 2018-11-27. Score: 1

Given an input file input.vcf, I would take this approach:

Create two text files: one with the male sample names (males.txt) and one with the female sample names (females.txt) (one sample per line)
Create a BCF (for speed) for all the samples in each list while dropping the INFO field so that INFO/AC is recalculated (I'm not sure dropping the INFO field is strictly necessary). Then only keep sites with a minor allele count greater than zero:
bcftools view --samples-file males.txt input.vcf -Ou | bcftools annotate -x INFO  -Ou | bcftools view --min-ac 1:minor -Ob -o male_variants.bcf
bcftools view --samples-file females.txt input.vcf -Ou | bcftools annotate -x INFO -Ou | bcftools view --min-ac 1:minor -Ob -o female_variants.bcf

Use isec to create intersects and complements of the two variant files and store them in dir/*:
bcftools isec male_variants.bcf female_variants.bcf -p dir -Oz


Double-check dir/README.txt, but the files you seek should be named dir/0000.vcf.gz and dir/0001.vcf.gz
Disclaimer: This code is untested.


---

### Answer by username_2 on 2018-11-27. Score: 1

if you could provide seperate list of male and female samples names you can something like this:
$ bcftools view -e 'GT[@males.txt]!="0/1" && GT[@females.txt]!="0/0"' combined.vcf.gz

or if you don't want to take care of the exact genotype you can write it more generic:
$ bcftools view -e 'GT[@males.txt]!="alt" && GT[@females.txt]!="ref"' combined.vcf.gz

fin swimmer


---

### Answer by username_3 on 2018-11-28. Score: 1

using vcffilterjdk  http://lindenb.github.io/jvarkit/VcfFilterJdk.html

or ask for all individuals named *.M and *.F.

java -jar dist/vcffilterjdk.jar -e 'return variant.getGenotypes().stream().allMatch(G->(G.getSampleName().endsWith("M") && G.isHet()) || (G.getSampleName().endsWith("F") && G.isHomRef())); ' input.vcf

variant.getGenotypes().stream() get a stream of genotypes 'G' for the current variant.  
allMatch all genotypes must match the statements below:
G.getSampleName().endsWith("M") && G.isHet() sample 's name ends with 'M' and is heterozygous
OR
G.getSampleName().endsWith("F") && G.isHet() sample 's name ends with 'F' and is Hom-ref


---

