R/which.edge.R

## which.edge.R (2009-05-10)

##   Identifies Edges of a Tree

## Copyright 2004-2009 Emmanuel Paradis

## This file is part of the R-package `ape'.
## See the file ../COPYING for licensing issues.

getMRCA <- function(phy, tip)
### Find the MRCA of the tips given as `tip'
### (see `root.R' for comments on the code)
{
    Ntip <- length(phy$tip.label)
    seq.nod <- .Call("seq_root2tip", phy$edge, Ntip,
                     phy$Nnode, PACKAGE = "ape")
    sn <- seq.nod[tip]
    MRCA <- Ntip + 1
    i <- 2
    repeat {
        x <- unique(unlist(lapply(sn, "[", i)))
        if (length(x) != 1) break
        MRCA <- x
        i <- i + 1
    }
    MRCA
}

which.edge <- function(phy, group)
{
    if (!inherits(phy, "phylo"))
      stop('object "phy" is not of class "phylo"')
    if (is.character(group))
      group <- which(phy$tip.label %in% group)
    if (length(group) == 1)
      return(match(group, phy$edge[, 2]))
    nb.tip <- length(phy$tip.label)
    MRCA <- getMRCA(phy, group)
    if (MRCA == nb.tip + 1) {
        from <- 1
        to <- dim(phy$edge)[1]
    } else {
        from <- which(phy$edge[, 2] == MRCA) + 1
        to <- max(which(phy$edge[, 2] %in% group))
    }
    wh <- from:to
    tmp <- phy$edge[wh, 2]
    ## check that there are no extra tips:
    ## (we do this by selecting the tips in `group' and the nodes
    ##  i.e., the internal edges)
    test <- tmp %in% group | tmp > nb.tip
    if (any(!test)) {
        wh <- wh[test] # drop the extra tips
        ## see if there are no extra internal edges:
        tmp <- phy$edge[wh, ]
        test <- !(tmp[, 2] %in% tmp[, 1]) & tmp[, 2] > nb.tip
        while (any(test)){
            wh <- wh[!test]
            tmp <- phy$edge[wh, ]
            test <- !(tmp[, 2] %in% tmp[, 1]) & tmp[, 2] > nb.tip
        }
    }
    wh
}
gjuggler/ape documentation built on May 17, 2019, 6:03 a.m.