<p>If we can always assume your fields will be <code>GT:AD:DP:GQ:PL</code>, you can use this relatively simple, brute approach awk script:</p>

<pre><code>awk -vOFS="\t" -F"\t" '{
  ## just print the header lines
  if(/^#/){
    print;
  }
  else{    
    ## The number of samples will be the extra number of fields 
    ## in addition to the default VCF 9
    sampleNum = NF - 9
    ## Fix each sample
    for(i=1; i&lt;=sampleNum; i++){
      ## get the fields
      num=split(<span class="math-container">$(9+i), fields,":");
      ## genotype
      if(fields[1] ~ "0/0"){ fields[1] = "1/1"}
      else if(fields[1] == "1/1"){ fields[1] = "0/0" }
      else if(fields[1] == "0/1"){ fields[1] = "1/0" }
      else if(fields[1] == "1/0"){ fields[1] = "0/1" }
      ## AD
      split(fields[2],values,",")
      fields[2] = values[2]","values[1]
      ## PL
      split(fields[2],values,",")
      ## Now set these as the sample data
      $</span>(9+i) = fields[1];
      for(k=2;k&lt;=num;k++){
        <span class="math-container">$(9+i) = $</span>(9+i)":"fields[k]
      }
    }
    print;
  }
}' file.vcf
</code></pre>

<p>On your example input, this returns:</p>

<pre><code>Contig111   11  Contig111_11_T_G    T   G   4278.22 PASS    AC=8;AF=0.073;AN=110;BaseQRankSum=1.35;DP=1176;ExcessHet=0.1448;FS=1.841;InbreedingCoeff=0.1904;QD=13.41;ReadPosRankSum=0.351;set=Intersection  GT:AD:DP:GQ:PL  1/1:0,17:17:48:0,48,720 1/0:8,14:22:99:167,0,347    .....
</code></pre>

CC BY-SA 4.0
2019-07-04T07:34:52.527Z
thanks @terdon, I guess this means we don't really have a software able to handle it and I'll need to dive into scripting :) your solution works so i'll accept it, although I'd prefer to use some available software in this case.
aechchiki
CC BY-SA 4.0
2019-07-04T08:11:08.557Z
@aechchiki yeah, I doubt there will be software for this since you are doing something that is very much not standard: you are swapping data around between different alleles.
terdon
CC BY-SA 4.0
2019-07-03T14:36:00.260Z
2019-07-03T14:36:00.260Z
terdon
<p>Is there a tool already established to "swap" the ref/alt information in the <code>GT</code>, <code>AD</code> and <code>PL</code> fields of a <code>vcf</code> file?</p>

<p>For the <code>GT</code> field, I need to transform: <code>0/0 -&gt; 1/1</code> ;  <code>1/1 -&gt; 0/0</code> ;  <code>0/1 -&gt; 1/0</code> ; and finally <code>1/0 -&gt; 0/1</code></p>

<p>For the <code>AD</code> field, I need to swap the columns: <code>x,y -&gt; y,x</code></p>

<p>For the <code>PL</code> field, I need to swap the columns: <code>x,y,z -&gt; z,y,x</code></p>

<p>Sample input: </p>

<pre><code>Contig111   11  Contig111_11_T_G    T   G   4278.22 PASS    AC=8;AF=0.073;AN=110;BaseQRankSum=1.35;DP=1176;ExcessHet=0.1448;FS=1.841;InbreedingCoeff=0.1904;QD=13.41;ReadPosRankSum=0.351;set=Intersection  GT:AD:DP:GQ:PL  0/0:17,0:17:48:0,48,720 0/1:14,8:22:99:167,0,347 .....
</code></pre>

<p>Sample output:</p>

<pre><code>    Contig111   11  Contig111_11_T_G    T   G   4278.22 PASS    AC=8;AF=0.073;AN=110;BaseQRankSum=1.35;DP=1176;ExcessHet=0.1448;FS=1.841;InbreedingCoeff=0.1904;QD=13.41;ReadPosRankSum=0.351;set=Intersection  GT:AD:DP:GQ:PL  1/1:0,17:17:48:720,48,0 1/0:8,14:22:99:347,0,167 .....
</code></pre>

<p>note: the same operations will need to be carried out for all samples if the VCF file has multiple samples (the <code>...</code> stand for other potential samples).</p>

<p>Before I dive into scripting ( basically playing with regex), I would like to know if something to process this is already available. I looked into <a href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwjpz7e77pjjAhU14KYKHdpiD5UQFjAAegQIARAB&amp;url=https%3A%2F%2Fsamtools.github.io%2Fbcftools%2Fbcftools.html&amp;usg=AOvVaw0zRNAyxe78GwcQ_MweVbi1" rel="nofollow noreferrer">bcftools</a> and <a href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=5&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwingcLE7pjjAhVI0aYKHXHbD6kQFjAEegQIABAB&amp;url=https%3A%2F%2Fgithub.com%2Fsamtools%2Fbcftools%2Fissues%2F806&amp;usg=AOvVaw1Jw-IzAWoMXgaN-bxeGSlV" rel="nofollow noreferrer">fixref</a> but they don't seem to help for this. </p>

CC BY-SA 4.0
2019-07-03T13:54:01.733Z
What do you mean by "note: the ... stand for other columns to be swapped as well,"? You mean carry out the same operations on the GT, AD and PL of any other samples in the VCF file?
terdon
CC BY-SA 4.0
2019-07-03T13:54:29.723Z
yes, better wording here! thanks
aechchiki
CC BY-SA 4.0
2019-07-03T13:56:28.700Z
How generic does this need to be? I mean, is it enough to give you a solution that works specifically for the order of fields you have (`GT:AD:DP:GQ:PL`) or do we also need to be able to cope with different orders (so need to infer the position of the AD field from the INFO field)?
terdon
CC BY-SA 4.0
2019-07-03T13:58:25.167Z
for now, a solution for the order of fields I have is okay. I don't have a lot of experience with vcf file, and I thought that the order of fields was "fixed" for all vcfs :9
aechchiki
<vcf><file-formats><variant-calling><text-processing>
swap genotypes for specific fields of a vcf file
# swap genotypes for specific fields of a vcf file

(Asked by: username_0 on 2019-07-03)

Is there a tool already established to "swap" the ref/alt information in the GT, AD and PL fields of a vcf file?
For the GT field, I need to transform: 0/0 -> 1/1 ;  1/1 -> 0/0 ;  0/1 -> 1/0 ; and finally 1/0 -> 0/1
For the AD field, I need to swap the columns: x,y -> y,x
For the PL field, I need to swap the columns: x,y,z -> z,y,x
Sample input: 
Contig111   11  Contig111_11_T_G    T   G   4278.22 PASS    AC=8;AF=0.073;AN=110;BaseQRankSum=1.35;DP=1176;ExcessHet=0.1448;FS=1.841;InbreedingCoeff=0.1904;QD=13.41;ReadPosRankSum=0.351;set=Intersection  GT:AD:DP:GQ:PL  0/0:17,0:17:48:0,48,720 0/1:14,8:22:99:167,0,347 .....

Sample output:
    Contig111   11  Contig111_11_T_G    T   G   4278.22 PASS    AC=8;AF=0.073;AN=110;BaseQRankSum=1.35;DP=1176;ExcessHet=0.1448;FS=1.841;InbreedingCoeff=0.1904;QD=13.41;ReadPosRankSum=0.351;set=Intersection  GT:AD:DP:GQ:PL  1/1:0,17:17:48:720,48,0 1/0:8,14:22:99:347,0,167 .....

note: the same operations will need to be carried out for all samples if the VCF file has multiple samples (the ... stand for other potential samples).
Before I dive into scripting ( basically playing with regex), I would like to know if something to process this is already available. I looked into bcftools and fixref but they don't seem to help for this.

**Tags:** vcf, file-formats, variant-calling, text-processing
> **Comments:**
> **username_1**: What do you mean by "note: the ... stand for other columns to be swapped as well,"? You mean carry out the same operations on the GT, AD and PL of any other samples in the VCF file?  
> **username_0**: yes, better wording here! thanks  
> **username_1**: How generic does this need to be? I mean, is it enough to give you a solution that works specifically for the order of fields you have (`GT:AD:DP:GQ:PL`) or do we also need to be able to cope with different orders (so need to infer the position of the AD field from the INFO field)?  
> **username_0**: for now, a solution for the order of fields I have is okay. I don't have a lot of experience with vcf file, and I thought that the order of fields was "fixed" for all vcfs :9  

---

## 1 answers

### Answer by username_1 on 2019-07-03. Score: 1 | Accepted answer

If we can always assume your fields will be GT:AD:DP:GQ:PL, you can use this relatively simple, brute approach awk script:
awk -vOFS="\t" -F"\t" '{
  ## just print the header lines
  if(/^#/){
    print;
  }
  else{    
    ## The number of samples will be the extra number of fields 
    ## in addition to the default VCF 9
    sampleNum = NF - 9
    ## Fix each sample
    for(i=1; i<=sampleNum; i++){
      ## get the fields
      num=split($(9+i), fields,":");
      ## genotype
      if(fields[1] ~ "0/0"){ fields[1] = "1/1"}
      else if(fields[1] == "1/1"){ fields[1] = "0/0" }
      else if(fields[1] == "0/1"){ fields[1] = "1/0" }
      else if(fields[1] == "1/0"){ fields[1] = "0/1" }
      ## AD
      split(fields[2],values,",")
      fields[2] = values[2]","values[1]
      ## PL
      split(fields[2],values,",")
      ## Now set these as the sample data
      $(9+i) = fields[1];
      for(k=2;k<=num;k++){
        $(9+i) = $(9+i)":"fields[k]
      }
    }
    print;
  }
}' file.vcf

On your example input, this returns:
Contig111   11  Contig111_11_T_G    T   G   4278.22 PASS    AC=8;AF=0.073;AN=110;BaseQRankSum=1.35;DP=1176;ExcessHet=0.1448;FS=1.841;InbreedingCoeff=0.1904;QD=13.41;ReadPosRankSum=0.351;set=Intersection  GT:AD:DP:GQ:PL  1/1:0,17:17:48:0,48,720 1/0:8,14:22:99:167,0,347    .....

> **Comments:**
> **username_0**: thanks @terdon, I guess this means we don't really have a software able to handle it and I'll need to dive into scripting :) your solution works so i'll accept it, although I'd prefer to use some available software in this case.  
> **username_1**: @aechchiki yeah, I doubt there will be software for this since you are doing something that is very much not standard: you are swapping data around between different alleles.  

---

