Nothing
## function to simulate a pure-birth phylogenetic tree or trees
## written by Liam J. Revell 2011-2015, 2018
pbtree<-function(b=1,d=0,n=NULL,t=NULL,scale=NULL,nsim=1,
type=c("continuous","discrete"),...){
# get arguments
if(hasArg(ape)) ape<-list(...)$ape
else ape<-TRUE
if(hasArg(quiet)) quiet<-list(...)$quiet
else quiet<-FALSE
if(hasArg(extant.only)) extant.only<-list(...)$extant.only
else extant.only<-FALSE
if(hasArg(max.count)) max.count<-list(...)$max.count
else max.count<-1e5
if(hasArg(method)) method<-list(...)$method
else method<-"rejection"
if(hasArg(tip.label)){
tip.label<-list(...)$tip.label
if(!is.null(tip.label)){
if(is.null(n)){
tip.label<-NULL
cat("Warning: tip.label not allowed for n=NULL.\n")
cat(" using default labels\n")
} else if(length(tip.label)==n){
if(d>0){
cat("Warning: only using labels in tip.label for extant tips.\n")
cat(" extinct tips will be labeled X1, X2, etc.\n")
}
} else if(length(tip.label)!=n) {
cat("Warning: length(tip.label) and n do not match.\n")
cat(" using default labels\n")
tip.label<-NULL
}
}
} else tip.label<-NULL
type<-matchType(type[1],c("continuous","discrete"))
if(type=="discrete"){
if((b+d)>1){
cat("Warning:\n b + d cannot exceed 1.0 in discrete-time simulations\n")
cat(paste(" setting b & d to",b/(b+d),"and",d/(b+d),"respectively\n"))
b<-b/(b+d)
d<-d/(b+d)
}
}
tol<-1e-12
# done get arguments
# if nsim > 1 replicate nsim times
if(nsim>1){
trees<-replicate(nsim,pbtree(b,d,n,t,scale,type=type,ape=ape,quiet=quiet,extant.only=extant.only,method=method,tip.label=tip.label),simplify=FALSE)
class(trees)<-"multiPhylo"
return(trees)
} else {
if(!is.null(n)) NN<-n else NN<-NULL
if(!is.null(n)&&!is.null(t)){
if(method=="rejection"){
# simulate taxa & time stop using rejection sampling to max.count
if(!quiet){
cat("simulating with both taxa-stop (n) and time-stop (t) is\n")
cat("performed via rejection sampling & may be slow\n\n")
}
N<-0; T<-0; count<--1
while((N!=n||T<t)&&count<max.count){
tree<-pbtree(b,d,t=t,type=type,ape=FALSE,extant.only=extant.only,quiet=TRUE)
if(is.null(tree)) N<-T<-0
else {
N<-if(d>0&&extant.only==FALSE) length(getExtant(tree)) else length(tree$tip.label)
T<-max(nodeHeights(tree))
}
count<-count+1
}
if(N==n&&T>=(t-tol)){
if(!quiet) cat(paste(" ",count," trees rejected before finding a tree\n\n",sep=""))
} else {
if(!quiet) cat(paste(" max count of ",count," reached without finding a tree\n\n",sep=""))
tree<-NULL
}
# done simulate taxa & time stop
} else if(method=="direct"){
# simulate using direct sampling (experimental)
if(!quiet){
cat("simulating with both taxa-stop (n) & time-stop (t) using\n")
cat("'direct' sampling. this is experimental\n")
}
m<-2
while(m[length(m)]!=n){
ll<-bd<-vector(); m<-2; i<-1
while(sum(ll)<t){
ll[i]<-rexp(n=1,rate=m[i]*(b+d))
if(sum(ll)<t) bd[i]<-2*rbinom(n=1,size=1,prob=b/(b+d))-1 else bd[i]<-0
m[i+1]<-m[i]+bd[i]; i<-i+1
if(m[i]==0) break
}
}
ll[length(ll)]<-ll[length(ll)]+t-sum(ll)
bd<-bd
node<-1; dead<-1
edge<-matrix(c(node,NA,node,NA),2,2,byrow=T)
edge.length<-c(0,0)
node<-node+1
for(i in 1:length(bd)){
o<-is.na(edge[,2])
p<-which(o)
l<-ll[i]
birth<-if(bd[i]==1) TRUE else FALSE
q<-if(length(p)>1) sample(p,size=1) else p
if(birth){
# new edge
edge[q,2]<-node
edge<-rbind(edge,matrix(c(node,NA,node,NA),2,2,byrow=T))
node<-node+1
} else {
edge[q,2]<--dead
dead<-dead+1
}
edge.length[p]<-edge.length[p]+l
if(birth) edge.length<-c(edge.length,rep(0,2))
}
edge[edge[,2]<0,2]<-NA
o<-is.na(edge[,2])
n<-sum(o)
edge<-edge+n
p<-which(o)
edge[o,2]<-1:sum(is.na(edge[,2]))
# build 'phylo' object
tree<-list(edge=edge,edge.length=edge.length,tip.label=paste("t",1:n,sep=""),Nnode=n-1)
class(tree)<-"phylo"
# done simulate using direct sampling (experimental)
}
} else {
if(!is.null(t)){
# simulation time stop
node<-1; dead<-1
edge<-matrix(c(node,NA,node,NA),2,2,byrow=T)
edge.length<-c(0,0)
node<-node+1; tt<-0
while(tt<t){
o<-is.na(edge[,2])
if(!any(o)) break
p<-which(o)
if(type=="discrete"){
l<-rgeom(n=sum(o),prob=b+d)+1
l<-l[which(l==min(l))]
} else l<-rexp(n=1,sum(o)*(b+d))
tt<-tt+l[1]
if(tt>=t) l<-l-tt+t
else {
birth<-sapply(runif(n=length(l)),function(x) if(x<b/(b+d)) TRUE else FALSE)
q<-if(length(p)>1) sample(p)[1:min(length(p),length(l))] else p
for(i in 1:length(l)){
if(birth[i]){
# new edge
edge[q[i],2]<-node
edge<-rbind(edge,matrix(c(node,NA,node,NA),2,2,byrow=T))
node<-node+1
} else {
edge[q[i],2]<--dead
dead<-dead+1
}
}
}
edge.length[p]<-edge.length[p]+l[1]
edge.length<-c(edge.length,rep(0,2*length(l)))
}
edge[edge[,2]<0,2]<-NA
o<-is.na(edge[,2])
n<-sum(o)
edge<-edge+n
p<-which(o)
edge[o,2]<-1:sum(is.na(edge[,2]))
# done unique part of time stop
} else if(!is.null(n)) {
# simulate taxa stop
node<-1
edge<-matrix(c(node,NA,node,NA),2,2,byrow=T)
edge.length<-c(0,0)
node<-node+1; dead<-1; nn<-2
while(nn<n){
o<-is.na(edge[,2])
if(!any(o)) break
p<-which(o)
if(type=="discrete"){
l<-rgeom(n=sum(o),prob=b+d)+1
l<-l[which(l==min(l))]
} else l<-rexp(n=1,sum(o)*(b+d))
birth<-birth<-sapply(runif(n=length(l)),function(x) if(x<b/(b+d)) TRUE else FALSE)
q<-if(length(p)>1) sample(p)[1:min(length(p),length(l))] else p
for(i in 1:length(l)){
if(birth[i]){
# new edge
edge[q[i],2]<-node
edge<-rbind(edge,matrix(c(node,NA,node,NA),2,2,byrow=T))
node<-node+1
} else {
edge[q[i],2]<--dead
dead<-dead+1
}
}
edge.length[p]<-edge.length[p]+l[1]
edge.length<-c(edge.length,rep(0,2*length(l)))
nn<-sum(is.na(edge[,2]))
}
edge[edge[,2]<0,2]<-NA
o<-is.na(edge[,2])
nn<-sum(o)
edge<-edge+nn
p<-which(o)
l<-if(type=="discrete") min(rgeom(n=sum(o),prob=(b+d))+1) else rexp(n=1,sum(o)*(b+d))
edge.length[p]<-edge.length[p]+l
edge[is.na(edge[,2]),2]<-1:sum(is.na(edge[,2]))
if((nn-dead+1)>n&&!quiet){
# this might happen in discrete time only
cat("Warning:\n due to multiple speciation events in the final time interval\n")
cat(" realized n may not equal input n\n\n")
if(!is.null(tip.label)){
cat("Warning: length(tip.label) and n do not match.\n")
cat(" using default labels\n")
tip.label<-NULL
}
}
n<-nn
# done unique part of taxa stop
}
# build 'phylo' object with temporary labels
tree<-list(edge=edge,edge.length=edge.length,tip.label=1:n,Nnode=n-1)
class(tree)<-"phylo"
if(!is.null(scale)){
# rescale if scale!=NULL
h<-max(nodeHeights(tree))
tree$edge.length<-scale*tree$edge.length/h
}
if(d>0&&extant.only){
# prune extinct tips if extant.only==TRUE
if(length(getExtinct(tree))==(length(tree$tip.label)-1)){
if(!quiet) cat("Warning:\n no extant tips, tree returned as NULL\n")
tree<-NULL
} else tree<-drop.tip(tree,getExtinct(tree))
}
# if tree!=NULL assign final tip labels
if(!is.null(tree)) tree$tip.label<-paste("t",1:length(tree$tip.label),sep="")
}
# if ape==TRUE make sure 'phylo' is consistent with ape
if(ape&&is.null(tree)==FALSE) tree<-read.tree(text=write.tree(tree))
if(!is.null(tip.label)){
th<-max(nodeHeights(tree))
if(length(getExtant(tree,tol=1e-08*th))!=NN){
# simulation must have gone extint before reaching NN
tree$tip.label<-paste("X",1:length(tree$tip.label),sep="")
} else {
ll<-getExtant(tree,tol=1e-08*th)
ii<-sapply(ll,function(x,y) which(x==y),y=tree$tip.label)
tree$tip.label[ii]<-tip.label
tree$tip.label[-ii]<-paste("X",1:(length(tree$tip.label)-length(ii)),sep="")
}
}
# done
return(tree)
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.