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!