Skip to content

Instantly share code, notes, and snippets.

@willpearse
Created June 29, 2017 21:51
Show Gist options
  • Save willpearse/f65bb3789e53c7c7f9e496e8f8150c1a to your computer and use it in GitHub Desktop.
Save willpearse/f65bb3789e53c7c7f9e496e8f8150c1a to your computer and use it in GitHub Desktop.
A general way to bind a phylogeny to replace a given species on another phylogeny
# Functions
library(caper)
find.clade <- function(tree, tips){
clade.mat <- clade.matrix(tree)$clade.matrix
sums <- rowSums(clade.mat)
ancestors <- apply(clade.mat, 1, function(x) all(x[tips]==1))
sums[!ancestors] <- length(tree$tip.label)
return(unname(which.min(sums)))
}
bind.replace <- function(backbone, donor, replacing.tip.label){
size <- max(branching.times(donor))
bind.point <- which(backbone$tip.label == replacing.tip.label)
tree <- bind.tree(backbone, donor, where=bind.point)
clade <- find.clade(tree, which(tree$tip.label %in% donor$tip.label))
which.edge <- which(tree$edge[,2] == clade)
if(tree$edge.length[which.edge] < size)
stop("Donor phylogeny too large for backbone phylogeny")
tree$edge.length[which.edge] <- tree$edge.length[which.edge] - size
return(tree)
}
# Example
library(geiger)
tree <- sim.bdtree(n=10)
donor <- sim.bdtree(n=3)
donor$tip.label <- letters[seq_along(donor$tip.label)]
plot(tree)
plot(bind.replace(tree, donor, "s4")) #... you should change the tip label to be something you want bound in
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment