<p>I suggest you use <code>zip()</code> to transform your data into columns and then apply the following counts similar to <a href="https://bioinformatics.stackexchange.com/a/4955/104">heathobrien suggests</a>:</p>

<pre><code>from Bio import AlignIO

alignment = AlignIO.read(open('example.phy'), 'phylip')

var1 = var2 = var3 = 0
for col in zip(*alignment):
    num_unique = len(set(col))
    if num_unique == 1 and col[0] != '-':
        var1 += 1
    elif num_unique &gt; 1 and '-' not in col:
        var2 += 1
    elif '-' in col:  # assumes 1 or more dashes
        var3 += 1

print('Number of columns with the same amino acid: {}\n'
      'Number of columns with at least 2 amino acids (no gaps): {}\n'
      'Number of columns with at least one gap: {}'
       .format(var1, var2, var3))
</code></pre>

<p>For your example data, this outputs:</p>

<pre><code>Number of columns with the same amino acid: 9
Number of columns with at least 2 amino acids (no gaps): 40
Number of columns with at least one gap: 1
</code></pre>

CC BY-SA 4.0
2018-08-30T09:18:18.373Z
2018-08-30T09:18:18.373Z
Chris_Rands
<p>using something like <code>for col in column(alignment):</code></p>

<ol>
<li><p>I may get the number of columns which have all the same letters (amino acids)</p>

<pre><code>len(set(col)) == 1
</code></pre></li>
<li><p>The number of columns which have at least 2 different amino acids (with no dashes):</p>

<pre><code>len(set(col)) &gt; 1 and '-' not in col
</code></pre></li>
<li><p>The number of columns which have any single dash:</p>

<pre><code>'-' in col
</code></pre></li>
</ol>

<p>or if you really want columns with a single dash:</p>

<pre><code>    col.count('-') == 1
</code></pre>

CC BY-SA 4.0
2018-08-30T05:26:27.563Z
Earlier I have used a for loop to iterate over the columns `for c in column(alignment):` and get the columns with dashes `if "-" in c:
        list2.append(c)`
 and without dashes     `else:
        list3.append(c)`
 in two separate lists. But when it comes to count the total number of columns with dashes, it results out the number of dashes for each of the column in file and keeps on printing unless all the columns are iterated (because of for loop).
Sidra Younas
CC BY-SA 4.0
2018-08-30T06:41:12.670Z
It would be helpful if you can elaborate me what you have suggested because I cannot follow up the idea. I still have my problem. 1) I may get the number of columns which have all the same letters (amino acids) **2)**The number of columns which have at least 2 different amino acids (with no dashes). **3)**The number of columns which have any single dash. –
Sidra Younas
CC BY-SA 4.0
2018-08-29T21:22:12.313Z
2018-08-29T21:22:12.313Z
heathobrien
<p>I have been using python 3.6 and biopython 1.72 to work with protein data files. I am using a protein sequence file (phylip format), for example:</p>

<pre><code>    14    678
Zebrafish  LSSCGVVSGD LISVILPASS LEETQTSSAA AHQTHTDQQA GGSHVSSSSS 
Fugu       LASCGIVSGD LIRVALIRAA LMAADAPDRA DDGGGHSEQA VAMATNQVS- 
Chicken    LASCGIVSGD LIRVALIRAA LMAADAPDRA DDGGGHSEQA VAMATNQVS- 
Zebra      LASYGIVPGD LICLLLEETD AKSSLPPPSS SSPPSLQNGR ETSTLTPKNQ
</code></pre>

<p>I want to manipulate the file in a way so that;</p>

<ol>
<li>I may get the number of columns which have all the same letters (amino acids)</li>
<li>The number of columns which have at least 2 different amino acids (with no dashes).</li>
<li>The number of columns which have any single dash.</li>
</ol>

<p>I have iterated over the columns of the file with:</p>

<pre><code>alignment = AlignIO.read(open("example.phy"), "phylip") 
def column(alignment):
    n = len(alignment[0].seq)

    for i in range(n):
        c = []

        for record in alignment:
            c.append(record.seq[i])

        yield c
</code></pre>

<p>This returns the columns of the file, but I don't understand how I can manipulate them further.</p>

<p>Can I get some helpful suggestions?</p>

CC BY-SA 4.0
2018-08-30T09:38:34.067Z
BTW `alignment` and `sequence-alignment` tags should probably be synonyms
Chris_Rands
<phylogenetics><python><phylogeny>
Counting letters in phylip alignment columns with Biopython
# Counting letters in phylip alignment columns with Biopython

(Asked by: username_0 on 2018-08-29)

I have been using python 3.6 and biopython 1.72 to work with protein data files. I am using a protein sequence file (phylip format), for example:
    14    678
Zebrafish  LSSCGVVSGD LISVILPASS LEETQTSSAA AHQTHTDQQA GGSHVSSSSS 
Fugu       LASCGIVSGD LIRVALIRAA LMAADAPDRA DDGGGHSEQA VAMATNQVS- 
Chicken    LASCGIVSGD LIRVALIRAA LMAADAPDRA DDGGGHSEQA VAMATNQVS- 
Zebra      LASYGIVPGD LICLLLEETD AKSSLPPPSS SSPPSLQNGR ETSTLTPKNQ

I want to manipulate the file in a way so that;

I may get the number of columns which have all the same letters (amino acids)
The number of columns which have at least 2 different amino acids (with no dashes).
The number of columns which have any single dash.

I have iterated over the columns of the file with:
alignment = AlignIO.read(open("example.phy"), "phylip") 
def column(alignment):
    n = len(alignment[0].seq)

    for i in range(n):
        c = []

        for record in alignment:
            c.append(record.seq[i])

        yield c

This returns the columns of the file, but I don't understand how I can manipulate them further.
Can I get some helpful suggestions?

**Tags:** phylogenetics, python, phylogeny
> **Comments:**
> **username_1**: BTW `alignment` and `sequence-alignment` tags should probably be synonyms  

---

## 2 answers

### Answer by username_1 on 2018-08-30. Score: 3 | Accepted answer

I suggest you use zip() to transform your data into columns and then apply the following counts similar to heathobrien suggests:
from Bio import AlignIO

alignment = AlignIO.read(open('example.phy'), 'phylip')

var1 = var2 = var3 = 0
for col in zip(*alignment):
    num_unique = len(set(col))
    if num_unique == 1 and col[0] != '-':
        var1 += 1
    elif num_unique > 1 and '-' not in col:
        var2 += 1
    elif '-' in col:  # assumes 1 or more dashes
        var3 += 1

print('Number of columns with the same amino acid: {}\n'
      'Number of columns with at least 2 amino acids (no gaps): {}\n'
      'Number of columns with at least one gap: {}'
       .format(var1, var2, var3))

For your example data, this outputs:
Number of columns with the same amino acid: 9
Number of columns with at least 2 amino acids (no gaps): 40
Number of columns with at least one gap: 1


---

### Answer by username_2 on 2018-08-29. Score: 4

using something like for col in column(alignment):

I may get the number of columns which have all the same letters (amino acids)
len(set(col)) == 1

The number of columns which have at least 2 different amino acids (with no dashes):
len(set(col)) > 1 and '-' not in col

The number of columns which have any single dash:
'-' in col


or if you really want columns with a single dash:
    col.count('-') == 1

> **Comments:**
> **username_0**: Earlier I have used a for loop to iterate over the columns `for c in column(alignment):` and get the columns with dashes `if "-" in c:         list2.append(c)`  and without dashes     `else:         list3.append(c)`  in two separate lists. But when it comes to count the total number of columns with dashes, it results out the number of dashes for each of the column in file and keeps on printing unless all the columns are iterated (because of for loop).  
> **username_0**: It would be helpful if you can elaborate me what you have suggested because I cannot follow up the idea. I still have my problem. 1) I may get the number of columns which have all the same letters (amino acids) **2)**The number of columns which have at least 2 different amino acids (with no dashes). **3)**The number of columns which have any single dash. –  

---

