Hi Pasquale,

To follow up on my earlier message, I have written a preliminary version of a simple function to simultaneously estimate the evolutionary parameters and ancestral states for Brownian evolution with a trend using likelihood. I will paste it at the end of this email. I have confirmed that the function returns the same trend parameter as fitContinuous(model="trend") and the same ancestral character estimates as ace() - when mu (the trend parameter) is forced to zero [note that this can only be done by modifying the code]. The parameter "sig2," the Brownian rate, is biased by a factor n/(2n-2) for n species relative to fitContinuous(model="trend)$Trait1$beta.

Note that this model can generally only be fit for a tree with tips that are not contemporaneous - for instance, for a phylogeny containing fossil species.

Best, Liam

Function code (also http://anolis.oeb.harvard.edu/~liam/R-phylogenetics/anc.trend/v0.1/anc.trend.R):

# written by Liam J. Revell 2011
anc.trend<-function(phy,x,maxit=2000){

        # preliminaries
        # require dependencies
        require(ape)
        # set global
        tol<-1e-8
        # compute C
        D<-dist.nodes(phy)
        ntips<-length(phy$tip.label)
        Cii<-D[ntips+1,]
        C<-D; C[,]<-0
        counts<-vector()
        for(i in 1:nrow(D)) for(j in 1:ncol(D))
                C[i,j]<-(Cii[i]+Cii[j]-D[i,j])/2
        dimnames(C)[[1]][1:length(phy$tip)]<-phy$tip.label
        dimnames(C)[[2]][1:length(phy$tip)]<-phy$tip.label
        C<-C[c(1:ntips,(ntips+2):nrow(C)),c(1:ntips,(ntips+2):ncol(C))]
        # sort x by phy$tip.label
        x<-x[phy$tip.label]

        # function returns the negative log-likelihood
        likelihood<-function(theta,x,C){
                a<-theta[1]
                u<-theta[2]
                sig2<-theta[3]
                y<-theta[4:length(theta)]
                
logLik<-dmnorm(x=c(x,y),mean=(a+diag(C)*u),varcov=sig2*C,log=TRUE)
                return(-logLik)
        }

        # get reasonable starting values for the optimizer
        a<-mean(x)
        sig2<-var(x)/max(C)

        # perform ML optimization
        
result<-optim(par=c(a,0,sig2,rep(a,phy$Nnode-1)),likelihood,x=x,C=C,method="L-BFGS-B",lower=c(-Inf,-Inf,tol,rep(-Inf,phy$Nnode-1)),control=list(maxit=maxit))

        # return the result
ace<-c(result$par[c(1,4:length(result$par))]); names(ace)<-c(as.character(phy$edge[1,1]),rownames(C)[(length(phy$tip.label)+1):nrow(C)])
        
return(list(ace=ace,mu=result$par[2],sig2=result$par[3],logL=-result$value,convergence=result$convergence,message=result$message))

}

--
Liam J. Revell
University of Massachusetts Boston
web: http://www.bio.umb.edu/facstaff/faculty_Revell.html
(new) email: liam.rev...@umb.edu
(new) blog: http://phytools.blogspot.com

On 2/17/2011 12:45 PM, Liam J. Revell wrote:
Hi Pasquale,

I think this may be possible if all tips are not contemporaneous.

As Gene points out, the values at the tips of the tree given a trend
should be distributed as ~MVN(mu=diag(vcv(tree))*tr+ancestor,
V=vcv(tree)*sig2). Thus, we should be able to compute the likelihood of
any data pattern at the tips and internal nodes of the tree, given tr,
ancestor, and sig2. If we start with only the values at the tips and the
phylogeny, we can estimate the states at internal nodes and our model by
maximizing the likelihood. This would be our solution.

I have written down some code for this using dmnorm() (from the mnormt
package) to compute the multivariate normal density; a home-made
function to compute vcv(tree) but for all the nodes in the tree; and
optim() to maximize the likelihood - but it doesn't seem to work very
well yet. I will pass it along if I can figure it out.

- Liam


_______________________________________________
R-sig-phylo mailing list
R-sig-phylo@r-project.org
https://stat.ethz.ch/mailman/listinfo/r-sig-phylo

Reply via email to