BioPython phylo: collapsing nodes on tree if node in list and rename the respective collapsed node
1
0
Entering edit mode
6 months ago
Naomi Sun ▴ 10

I have a phylogenetic tree in Newick format, and I would like to remove all species from it that are on a specific list and rename it accordingly.

This is the tree:

((((A:0.1, B:0.2):0.3, C:0.3):0.15, (D:0.3, (E:0.1, (F:0.15, (G:0.1, H:0.1):0.1):0.1):0.1):0.1):0.15, I:0.2);

This is the table to rename:

| species | clade_renaming |
|------------|----------------|
| A, B       | X              |
| F, G, H    | Y              |

Expected result:

(((X:0.3, C:0.3):0.15, (D:0.3, (E:0.1, Y:0.1):0.1):0.1):0.15, I:0.2);

This is the current code that can collapse nodes:

from Bio import Phylo
import io

tree_structure = "((((A:0.1, B:0.2):0.3, C:0.3):0.15, (D:0.3, (E:0.1, (F:0.15, (G:0.1, H:0.1):0.1):0.1):0.1):0.1):0.15, I:0.2);"
tree = Phylo.read(io.StringIO(tree_structure), 'newick')

nodes_to_collapse = ["A", "B", "F", "G", "H"]

def collapse_nodes(tree, nodes_to_collapse):
    for node in tree.find_elements(target=lambda x: x.name in nodes_to_collapse, order="postorder"):
        tree.collapse(node)

collapse_nodes(tree, nodes_to_collapse)
Phylo.draw(tree)
phylogeny biopython • 551 views
ADD COMMENT
0
Entering edit mode

Hi,

Is this also you? Naomi Sun

ADD REPLY
1
Entering edit mode
6 months ago
Naomi Sun ▴ 10

This question has been answered in Stackoverflow: https://stackoverflow.com/questions/77973282/biopython-phylo-collapsing-nodes-on-tree-if-node-in-list-and-rename-the-respect.

Code shared by Umar:

from Bio import Phylo
import io

# Input tree and table
tree_structure = "((((A:0.1, B:0.2):0.3, C:0.3):0.15, (D:0.3, (E:0.1, (F:0.15, (G:0.1, H:0.1):0.1):0.1):0.1):0.1):0.15, I:0.2);"
rename_table = {"A, B": "X", "F, G, H": "Y"}

# Read the tree
tree = Phylo.read(io.StringIO(tree_structure), 'newick')

# Function to collapse and rename nodes
def collapse_and_rename(tree, rename_table):
    for nodes, new_name in rename_table.items():
        common_ancestor_names = [node.strip() for node in nodes.split(',')]
        common_ancestor = tree.common_ancestor(common_ancestor_names)

        # Calculate the total branch length of the collapsed node
        total_branch_length = sum(child.branch_length for child in common_ancestor.clades if child.branch_length is not None)

        # Set the new name for the common ancestor node
        common_ancestor.name = new_name

        # Adjust branch lengths of children
        for child in common_ancestor.clades:
            if child.branch_length:
                child.branch_length -= total_branch_length
        # Set the branch length of the collapsed node to the sum of its children's branch lengths
        common_ancestor.branch_length = total_branch_length



# Collapse and rename nodes
collapse_and_rename(tree, rename_table)

# Function to collapse nodes and update branch lengths
def collapse_nodes(tree, nodes_to_collapse):
    for node in tree.find_elements(target=lambda x: x.name in nodes_to_collapse, order="postorder"):
        tree.collapse(node)
nodes_to_collapse = ["A", "B", "F", "G", "H"]
# Collapse nodes and update branch lengths
collapse_nodes(tree, nodes_to_collapse)

# Draw the tree
Phylo.draw(tree)
ADD COMMENT
0
Entering edit mode

Thank you for posting the answer from your other post but please be mindful that it's not good practice to ask the same question on multiple communities without letting them know you've asked other communities as well.

I understand that you might be seeking visibility for your query, but I'd like to share with you that since there is a lot of user overlap between Biostars and Stack Exchange websites such as StackOverflow and Bioinformatics Stack Exchange, it ends up kind of being like contacting someone through email by using 2-3 different email IDs of theirs.

We encourage you to explore the forum and participate in various discussions. If you have any questions about how to use the forum effectively or need assistance with anything, please feel free to reach out.

ADD REPLY

Login before adding your answer.

Traffic: 1237 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6