<p>The following example uses python to generate the newick string. You can than import that in R for further analysis.</p>
<p>Please keep in mind that you can not use self reference for node4 (9,9,9), so I changed this to 'Root'.</p>
<pre><code>from ete3 import Tree
import pandas as pd

df = pd.DataFrame({'parent': [8, 8, 7, 6, 6, 7, 9, 9, 'Root'],
                   'node': [1, 2, 3, 4, 5, 6, 7, 8, 9],
                   'branch.length': [9, 9, 12, 14, 17, 19, 21, 23, 9],
                   'label': ['a', 'b', 'c', 'd', 'e', 'node1', 'node2', 'node3', 'node4']})


parent_child_list = df[['parent', 'node', 'branch.length']].apply(tuple, axis=1).tolist()
tree = Tree.from_parent_child_table(parent_child_list)
newick_str = tree.write(format=1)

</code></pre>
<p>newick_str:</p>
<pre><code>'(((3:12,(4:14,5:17)6:19)7:21,(1:9,2:9)8:23)9:9);'
</code></pre>

CC BY-SA 4.0
2023-03-11T11:46:29.803Z
Thank you! Exactly what I was looking for.
helle
CC BY-SA 4.0
2023-03-10T16:27:22.670Z
2023-03-10T16:27:22.670Z
Macintosh
<p>I have a dataset that I wish to convert to tree or phylo format like in the <code>ape</code> package, in order to plot the phylogenetic tree. It is formatted like a list of edges and species names for the leaves. The dataset is quite large, but I have made an example dataset that represents it:</p>
<pre class="lang-r prettyprint-override"><code>df &lt;- data.frame(c(8,8,7,6,6,7,9,9,9),
                c(1,2,3,4,5,6,7,8,9),
                c(9, 9, 12, 14, 17, 19, 21, 23, 9),
                c(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;,&quot;e&quot;, &quot;node1&quot;, &quot;node2&quot;, &quot;node3&quot;, &quot;node4&quot;))
names(df) &lt;- c(&quot;parent&quot;,&quot;node&quot;,&quot;branch.length&quot;, &quot;label&quot;)
</code></pre>
<p>I wish to plot it as a rooted phylogenetic tree using the <code>ape</code> package, but I can't figure out how to convert it to for example a newick string. I have tried to look at solutions both in R and Python, but I can't figure it out. Does anyone have any idea how this can be done?</p>
<p>Additional information: I also have two other vectors, one contains the length of each edge, and one containing the age of the child node, equal to the sum of all edge length from that child to any leaf of the tree. It would be great if this could be included, but not neccessary for the plotting as it is only illustrative.</p>
<p>Thanks!</p>
<p><strong>Update</strong></p>
<p>I am using R version 4.1.2.
One of my attempts at translating my data to Newick code (as i understand this could include the branch lengths), using one of [these answers].
I don't understand what goes wrong, but I have not worked with Newick code before so I am not very experienced with this.
(<a href="https://biology.stackexchange.com/questions/37057/construct-phylogeny-form-edgelist">https://biology.stackexchange.com/questions/37057/construct-phylogeny-form-edgelist</a>):</p>
<pre class="lang-r prettyprint-override"><code>df &lt;- data.frame(c(8,8,7,6,6,7,9,9,9),
                c(1,2,3,4,5,6,7,8,9),
                c(9, 9, 12, 14, 17, 19, 21, 23, 9),
                c(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;,&quot;e&quot;, &quot;node1&quot;, &quot;node2&quot;, &quot;node3&quot;, &quot;node4&quot;))
names(df) &lt;- c(&quot;parent&quot;,&quot;node&quot;,&quot;branch.length&quot;, &quot;label&quot;)
tree_data &lt;- df
str(tree_data)

tree_data<span class="math-container">$newick = paste(tree_data$</span>label,':',signif(tree_data<span class="math-container">$branch.length,3),sep="")
nparents = 2
  while(nparents &gt; 1){
  leaf = setdiff(tree_data$node,tree_data$parent)
  parent_leaf = unique(tree_data$parent[!is.na(match(tree_data$node,leaf))])
  index_remove = integer(0)
  for(i in 1:length(parent_leaf)){
parent_children = tree_data$node[which(tree_data$parent == parent_leaf[i])]
all_children_in_leaf = all(parent_children %in% leaf)
if(all_children_in_leaf==T){
  index_remove = c(index_remove,match(parent_children,tree_data$node))
  tree_data$newick[which(tree_data$node==parent_leaf[i])] = paste("(",paste(tree_data$newick[match(parent_children,tree_data$node)],collapse=" , "),")",tree_data$newick[which(tree_data$node==parent_leaf[i])] ,sep = " ")
}
  }
  tree_data = tree_data[-index_remove,]
  parent_next = unique(tree_data$parent[!is.na(match(tree_data$node,leaf))])
  nparents = length(parent_next)
  if (nparents==1) newick_code = paste("(",paste(tree_data$</span>newick,collapse=&quot;,&quot;),&quot;)&quot;,colnames(tree_data)[parent_next],&quot;;&quot;,sep = &quot; &quot;)
}


tree &lt;- ape::read.tree(text = newick_code)

plot.phylo(tree)

</code></pre>
<p>I don't get an error any more, but I get some unexpected output:</p>
<p><a href="https://i.sstatic.net/NXj2q.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/NXj2q.png" alt="The output I get" /></a></p>
<p>This is what I would expect, all nodes that are not single letters are inner nodes, not leaves:</p>
<p><a href="https://i.sstatic.net/G0lj5.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/G0lj5.png" alt="The output I want" /></a></p>
<p>I really appreciate any help!</p>

CC BY-SA 4.0
2023-03-07T22:22:27.410Z
There is an [answer](https://biology.stackexchange.com/questions/37057/construct-phylogeny-form-edgelist) to more or less the same question in biology.stackexchange.com.
Maximilian Press
CC BY-SA 4.0
2023-03-10T07:22:57.637Z
Thank you for the answer, I have taken a look at the answers but none of them seem to work for me.  (all return errors after reformatting to the data format they used) Nikunj Goel's answer of writing a code to translate to Newick code and include the branch lengths is what I have tried to do myself, but it is challenging as I am not very familiar with it.
helle
CC BY-SA 4.0
2023-03-10T09:09:09.243Z
Hi @Helle, can you provide a few lines of codes as well as the errors you are getting.   Include the version of R you are using. Those answers were published 7 yrs ago most likely you will have to adjust your code a bit to make it compatible with current standards.
Macintosh
CC BY-SA 4.0
2023-03-10T10:07:03.113Z
@Macintosh I have updated it now :-)
helle
CC BY-SA 4.0
2023-03-10T12:42:44.547Z
the error comes from colnames(Adj)[parent_next]: Adj is not defined and should refer to the correct table.
Macintosh
CC BY-SA 4.0
2023-03-10T13:15:07.727Z
Thanks, this helps. Now, it seems to have some trouble with the root node and "node2", they and up as leaves when I plot the tree.
helle
CC BY-SA 4.0
2023-03-10T13:18:28.990Z
yes there is indeed something off with that function. I suggest you make a comment in the post of NikunjGoel to add for advice! You can update the question with the Newick output and the expected newick output
Macintosh
CC BY-SA 4.0
2023-03-10T13:44:59.093Z
Unfortunately I don't have enough reputation comment or message anyone!
helle
CC BY-SA 4.0
2023-03-11T01:52:42.350Z
I have added a comment to that answer.
Maximilian Press
<r><python><phylogenetics><phylogeny>
Plot phylogenetic tree from list of edges
# Plot phylogenetic tree from list of edges

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

I have a dataset that I wish to convert to tree or phylo format like in the ape package, in order to plot the phylogenetic tree. It is formatted like a list of edges and species names for the leaves. The dataset is quite large, but I have made an example dataset that represents it:
df <- data.frame(c(8,8,7,6,6,7,9,9,9),
                c(1,2,3,4,5,6,7,8,9),
                c(9, 9, 12, 14, 17, 19, 21, 23, 9),
                c("a","b","c","d","e", "node1", "node2", "node3", "node4"))
names(df) <- c("parent","node","branch.length", "label")

I wish to plot it as a rooted phylogenetic tree using the ape package, but I can't figure out how to convert it to for example a newick string. I have tried to look at solutions both in R and Python, but I can't figure it out. Does anyone have any idea how this can be done?
Additional information: I also have two other vectors, one contains the length of each edge, and one containing the age of the child node, equal to the sum of all edge length from that child to any leaf of the tree. It would be great if this could be included, but not neccessary for the plotting as it is only illustrative.
Thanks!
Update
I am using R version 4.1.2.
One of my attempts at translating my data to Newick code (as i understand this could include the branch lengths), using one of [these answers].
I don't understand what goes wrong, but I have not worked with Newick code before so I am not very experienced with this.
(https://biology.stackexchange.com/questions/37057/construct-phylogeny-form-edgelist):
df <- data.frame(c(8,8,7,6,6,7,9,9,9),
                c(1,2,3,4,5,6,7,8,9),
                c(9, 9, 12, 14, 17, 19, 21, 23, 9),
                c("a","b","c","d","e", "node1", "node2", "node3", "node4"))
names(df) <- c("parent","node","branch.length", "label")
tree_data <- df
str(tree_data)

tree_data$newick = paste(tree_data$label,':',signif(tree_data$branch.length,3),sep="")
nparents = 2
  while(nparents > 1){
  leaf = setdiff(tree_data$node,tree_data$parent)
  parent_leaf = unique(tree_data$parent[!is.na(match(tree_data$node,leaf))])
  index_remove = integer(0)
  for(i in 1:length(parent_leaf)){
parent_children = tree_data$node[which(tree_data$parent == parent_leaf[i])]
all_children_in_leaf = all(parent_children %in% leaf)
if(all_children_in_leaf==T){
  index_remove = c(index_remove,match(parent_children,tree_data$node))
  tree_data$newick[which(tree_data$node==parent_leaf[i])] = paste("(",paste(tree_data$newick[match(parent_children,tree_data$node)],collapse=" , "),")",tree_data$newick[which(tree_data$node==parent_leaf[i])] ,sep = " ")
}
  }
  tree_data = tree_data[-index_remove,]
  parent_next = unique(tree_data$parent[!is.na(match(tree_data$node,leaf))])
  nparents = length(parent_next)
  if (nparents==1) newick_code = paste("(",paste(tree_data$newick,collapse=","),")",colnames(tree_data)[parent_next],";",sep = " ")
}


tree <- ape::read.tree(text = newick_code)

plot.phylo(tree)


I don't get an error any more, but I get some unexpected output:

This is what I would expect, all nodes that are not single letters are inner nodes, not leaves:

I really appreciate any help!

**Tags:** r, python, phylogenetics, phylogeny
> **Comments:**
> **username_1**: There is an [answer](https://biology.stackexchange.com/questions/37057/construct-phylogeny-form-edgelist) to more or less the same question in biology.stackexchange.com.  
> **username_0**: Thank you for the answer, I have taken a look at the answers but none of them seem to work for me.  (all return errors after reformatting to the data format they used) Nikunj Goel's answer of writing a code to translate to Newick code and include the branch lengths is what I have tried to do myself, but it is challenging as I am not very familiar with it.  
> **username_2**: Hi @Helle, can you provide a few lines of codes as well as the errors you are getting.   Include the version of R you are using. Those answers were published 7 yrs ago most likely you will have to adjust your code a bit to make it compatible with current standards.  
> **username_0**: @Macintosh I have updated it now :-)  
> **username_2**: the error comes from colnames(Adj)[parent_next]: Adj is not defined and should refer to the correct table.  
> **username_0**: Thanks, this helps. Now, it seems to have some trouble with the root node and "node2", they and up as leaves when I plot the tree.  
> **username_2**: yes there is indeed something off with that function. I suggest you make a comment in the post of NikunjGoel to add for advice! You can update the question with the Newick output and the expected newick output  
> **username_0**: Unfortunately I don't have enough reputation comment or message anyone!  
> **username_1**: I have added a comment to that answer.  

---

## 1 answers

### Answer by username_2 on 2023-03-10. Score: 4 | Accepted answer

The following example uses python to generate the newick string. You can than import that in R for further analysis.
Please keep in mind that you can not use self reference for node4 (9,9,9), so I changed this to 'Root'.
from ete3 import Tree
import pandas as pd

df = pd.DataFrame({'parent': [8, 8, 7, 6, 6, 7, 9, 9, 'Root'],
                   'node': [1, 2, 3, 4, 5, 6, 7, 8, 9],
                   'branch.length': [9, 9, 12, 14, 17, 19, 21, 23, 9],
                   'label': ['a', 'b', 'c', 'd', 'e', 'node1', 'node2', 'node3', 'node4']})


parent_child_list = df[['parent', 'node', 'branch.length']].apply(tuple, axis=1).tolist()
tree = Tree.from_parent_child_table(parent_child_list)
newick_str = tree.write(format=1)


newick_str:
'(((3:12,(4:14,5:17)6:19)7:21,(1:9,2:9)8:23)9:9);'

> **Comments:**
> **username_0**: Thank you! Exactly what I was looking for.  

---

