skembel/picante

Faulty assumption in node.age picks wrong root

FlukeAndFeather opened this issue · 1 comments

node.age assumes the root node in a tree tr is tr$edge[1, 1], but this is not necessarily the case. The documentation for ape::read.tree describes edge as:

a two-column matrix of mode numeric where each row represents an edge of the tree; the nodes and the tips are symbolized with numbers; the tips are numbered 1, 2, ..., and the nodes are numbered after the tips. For each row, the first column gives the ancestor.

So I think length(tr$tip.label) + 1 is always the root node, but not tr$edge[1, 1]. The sample code below encounters the bug for one of the trees used in Jetz et al., 2012 (Nature). If you change the first line of node.age to rootN = length(phy$tip.label) + 1 you don't get the error.

library(picante)
#> Loading required package: ape
#> Loading required package: vegan
#> Loading required package: permute
#> Loading required package: lattice
#> This is vegan 2.5-6
#> Loading required package: nlme
library(rotl)

tr <- get_study_tree("ot_809", "tree2")
node.age(tr)
#> Error in ages[n] <- anc.age + phy$edge.length[n]: replacement has length zero

Created on 2020-05-31 by the reprex package (v0.3.0)

Thanks for reporting this. I've updated the code to correct this as well as check for a rooted phylogeny when using node.age, and will submit an updated version of picante incorporating this change to CRAN shortly (version 1.8.2).