Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-11T11:46:29.803Z
Answers.Text: Thank you! Exactly what I was looking for.
Answers.UserDisplayName: helle
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-10T16:27:22.670Z
Answers.LastActivityDate: 2023-03-10T16:27:22.670Z
Answers.UserDisplayName: Macintosh
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-07T22:22:27.410Z
Comments.Text: 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.
Comments.UserDisplayName: Maximilian Press
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-10T07:22:57.637Z
Comments.Text: 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.
Comments.UserDisplayName: helle
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-10T09:09:09.243Z
Comments.Text: 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.
Comments.UserDisplayName: Macintosh
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-10T10:07:03.113Z
Comments.Text: @Macintosh I have updated it now :-)
Comments.UserDisplayName: helle
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-10T12:42:44.547Z
Comments.Text: the error comes from colnames(Adj)[parent_next]: Adj is not defined and should refer to the correct table.
Comments.UserDisplayName: Macintosh
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-10T13:15:07.727Z
Comments.Text: 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.
Comments.UserDisplayName: helle
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-10T13:18:28.990Z
Comments.Text: 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
Comments.UserDisplayName: Macintosh
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-10T13:44:59.093Z
Comments.Text: Unfortunately I don't have enough reputation comment or message anyone!
Comments.UserDisplayName: helle
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-11T01:52:42.350Z
Comments.Text: I have added a comment to that answer.
Comments.UserDisplayName: Maximilian Press
Tags: <r><python><phylogenetics><phylogeny>
Title: Plot phylogenetic tree from list of edges
ThreadText: # 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:
  
  ```r
  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>):
  
  ```r
  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:
  
  [![The output I get](https://i.sstatic.net/NXj2q.png)](https://i.sstatic.net/NXj2q.png)
  
  This is what I would expect, all nodes that are not single letters are inner nodes, not leaves:
  
  [![The output I want](https://i.sstatic.net/G0lj5.png)](https://i.sstatic.net/G0lj5.png)
  
  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 @username_0, 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**: @username_2 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.  
  
  ---
  
  