Thursday, June 27, 2019

Some of the updates in the new CRAN version of phytools (0.6-99)

I recently put a new version of phytools on CRAN (phytools 0.6-99).

The last CRAN phytools release was 28 September 2018, so naturally there were quite a few updates.

The following is a non-comprehensive list:

  1. An update to the function dotTree to include column labels.

  2. A totally new function fitmultiMk to fit a multi-rate Mk model to discrete character data on the tree (here).

  3. The MCCR test for Pybus & Harvey's γ statistic when taxon sampling is incomplete (1, 2). This used to be in Dan Rabosky's package laser, but since laser is no longer available I thought I'd implement it in phytools.

  4. Another totally new function, fitpolyMk, to fit an Mk model to discrete character data with polymorphism.

  5. A new S3 plot method for fitpolyMk.

  6. A new function for phylogenetic imputation with multivariate continuous trait data (phylo.impute).

  7. An update to phylo.to.map to permit more than one observation per tip in the tree. (Also see: 1, 2, 3).

  8. A simple user-requested update to fancyTree for type="extinction" (here).

  9. A small fix to the function plotTree.wBars for fan-style trees.

  10. Various updates to the phytools function mcmcMk for Bayesian MCMC analysis of the Mk model of evolution for discete character traits.

  11. A new multi2di registered S3 method for the "simmap" object class (as well as di2multi and multi2di methods for other object classes too - such as "contMap" and "densityMap" object: here).

  12. Several new S3 methods for the "evol.rate.mcmc" object class.

  13. Updates to the 'phylogenetic scatterplot matrix' method of fancyTree (and also separation of the method to its own function: phyloScattergram).

  14. Some useful updates & fixes to the function geo.legend, as well as an entirely new function, geo.palette. (Also here.)

  15. Various updates to ltt95.

  16. Finally, a small but non-trivial update to cophylo to permit co-phylogenetic plotting when one or both trees have duplicate tip labels.

For all updates, check out a complete list of commits on the phytools GitHub page. This list is long & include lots of things that haven't been mentioned above, such as new object classes and methods.

Here's an example of plotting species distributions with a "phylo.to.map" object:

obj
## Object of class "phylo.to.map" containing:
## 
## (1) A phylogenetic tree with 8 tips and 7 internal nodes.
## 
## (2) A geographic map with range:
##      -33.75N, 5.27N
##      -74.01W, -29.36W.
## 
## (3) A table containing 65 geographic coordinates (may include
##     more than one set per species).
## 
## If optimized, tree nodes have been rotated to maximize alignment
## with the map when the tree is plotted in a rightwards direction.
plot(obj,direction="rightwards",colors=sapply(cols,
    make.transparent,0.4),
    pts=FALSE,ftype="off",cex.points=c(0,0),
    ftype="off",lwd=c(3,1))
for(i in 1:Ntip(obj$tree)){
    ii<-which(rownames(obj$coords)==obj$tree$tip.label[i])
    polygon(obj$coords[ii,2:1],
        col=make.transparent(cols[obj$tree$tip.label[i]],0.8),
        border="darkgrey")
}

plot of chunk unnamed-chunk-1

Monday, June 17, 2019

Update to plot.cophylo to permit duplicate tip labels in one or both trees

This morning a phytools user sent the following query to the R-sig-phylo list:

“I want to plot two phylogenetic trees face-to-face using phytools::cophylo function. I see there is no possibility to connect 2 or 3 same taxa in a tree to one taxon in the other tree (attached). Is there anyway doing this in R?”

It turned out that the problem is not precisely as states, as the researcher actually wanted to match Species_genus with Species_genus_1, Species_genus_2, & so on, which was already possible by specifying an association table using the function argument assoc (e.g., here).

On the other hand, I see no particular reason why a cophylo plot should not permit two tips in a tree to share precisely the same label. The only reason it did not work, it turns out, was due to a particular way in which the vertical positions of the linking lines were identified in the plotting method for the "cophylo" object. I just pushed an update to GitHub that should address this issue.

Here's a small demo using random trees (after updating phytools from GitHub using devtools::install_github:

library(phytools)
packageVersion("phytools")
## [1] '0.6.83'
set.seed(999)
t1<-rtree(n=16)
t2<-rtree(n=16)
plot(obj<-cophylo(t1,t2))
## Rotating nodes to optimize matching...
## Done.

plot of chunk unnamed-chunk-1

Now let's set some of our tip labels to be the same as each other:

t1$tip.label[which(t1$tip.label=="t16")]<-
    t1$tip.label[which(t1$tip.label=="t8")]<-"t5"
t2$tip.label[which(t2$tip.label=="t3")]<-"t4"
obj<-cophylo(t1,t2)
## Rotating nodes to optimize matching...
## Done.
summary(obj)
## 
## Co-phylogenetic ("cophylo") object: obj 
## 
## Tree 1 (left tree) is an object of class "phylo" containing 16 species.
## 
## Tree 2 (right tree) is an object of class "phylo" containing 16 species.
## 
## Association (assoc) table as follows:
## 
##  left:   ----    right:
##  t7  ----    t7
##  t5  ----    t5
##  t6  ----    t6
##  t2  ----    t2
##  t1  ----    t1
##  t14 ----    t14
##  t11 ----    t11
##  t10 ----    t10
##  t4  ----    t4
##  t9  ----    t9
##  t13 ----    t13
##  t15 ----    t15
##  t12 ----    t12
plot(obj,link.lwd=2,link.lty="dotted",
    link.col=make.transparent("red",0.5))

plot of chunk unnamed-chunk-2

We can also have duplicating tip labels with an association table. For instance:

for(i in 1:length(t2$tip.label)){
    ii<-as.numeric(strsplit(t2$tip.label[i],
        "t")[[1]][2])
    t2$tip.label[i]<-LETTERS[ii]
}
assoc<-cbind(paste("t",1:20,sep=""),
    LETTERS[1:20])
obj<-cophylo(t1,t2,assoc=assoc)
## Some species in assoc[,1] not in tr1. Removing species & links.
## Some species in assoc[,2] not in tr2. Removing species & links.
## Rotating nodes to optimize matching...
## Done.
summary(obj)
## 
## Co-phylogenetic ("cophylo") object: obj 
## 
## Tree 1 (left tree) is an object of class "phylo" containing 16 species.
## 
## Tree 2 (right tree) is an object of class "phylo" containing 16 species.
## 
## Association (assoc) table as follows:
## 
##  left:   ----    right:
##  t1  ----    A
##  t2  ----    B
##  t4  ----    D
##  t5  ----    E
##  t6  ----    F
##  t7  ----    G
##  t9  ----    I
##  t10 ----    J
##  t11 ----    K
##  t12 ----    L
##  t13 ----    M
##  t14 ----    N
##  t15 ----    O
plot(obj)

plot of chunk unnamed-chunk-3

Don't forget that phytools::plot.cophylo has lots of different options, such as using curved linking lines, e.g.:

plot(obj,link.type="curved",link.lwd=2,
    link.col=make.transparent("grey",0.7))

plot of chunk unnamed-chunk-4

That's it.