X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=R%2Froot.R;h=d02044fa627360bafaedf5055e8bfe3dce3d7d8c;hb=1090d5990d4b6f7feb10c87638f4229f53891eb7;hp=a11fa1e73d521a61dcddbe3f5bc863fef778109d;hpb=6696b292cb86cc4d6a6197830a7f3f7022f4f07e;p=ape.git diff --git a/R/root.R b/R/root.R index a11fa1e..d02044f 100644 --- a/R/root.R +++ b/R/root.R @@ -1,26 +1,25 @@ -## root.R (2008-06-12) +## root.R (2009-11-15) ## Root of Phylogenetic Trees -## Copyright 2004-2008 Emmanuel Paradis +## Copyright 2004-2009 Emmanuel Paradis ## This file is part of the R-package `ape'. ## See the file ../COPYING for licensing issues. is.rooted <- function(phy) { - if (!"phylo" %in% class(phy)) + if (!inherits(phy, "phylo")) stop('object "phy" is not of class "phylo"') - if (!is.null(phy$root.edge)) return(TRUE) + if (!is.null(phy$root.edge)) TRUE else if (tabulate(phy$edge[, 1])[length(phy$tip.label) + 1] > 2) - return(FALSE) - else return(TRUE) + FALSE else TRUE } unroot <- function(phy) { - if (class(phy) != "phylo") + if (!inherits(phy, "phylo")) stop('object "phy" is not of class "phylo"') if (dim(phy$edge)[1] < 3) stop("cannot unroot a tree with two edges.") @@ -36,11 +35,11 @@ unroot <- function(phy) ## nodes by adding 1, except the root (this remains the ## origin of the tree). nb.tip <- length(phy$tip.label) - ROOT <- nb.tip + 1 + ROOT <- nb.tip + 1L EDGEROOT <- which(phy$edge[, 1] == ROOT) ## j: the target where to stick the edge ## i: the edge to delete - if (phy$edge[EDGEROOT[1], 2] == ROOT + 1) { + if (phy$edge[EDGEROOT[1], 2] == ROOT + 1L) { j <- EDGEROOT[2] i <- EDGEROOT[1] } else { @@ -51,12 +50,12 @@ unroot <- function(phy) ## cladewise order. phy$edge <- phy$edge[-i, ] nodes <- phy$edge > ROOT # renumber all nodes except the root - phy$edge[nodes] <- phy$edge[nodes] - 1 + phy$edge[nodes] <- phy$edge[nodes] - 1L if (!is.null(phy$edge.length)) { phy$edge.length[j] <- phy$edge.length[j] + phy$edge.length[i] phy$edge.length <- phy$edge.length[-i] } - phy$Nnode <- phy$Nnode - 1 + phy$Nnode <- phy$Nnode - 1L if (!is.null(phy$node.label)) phy$node.label <- phy$node.label[-2] phy @@ -64,10 +63,9 @@ unroot <- function(phy) root <- function(phy, outgroup, node = NULL, resolve.root = FALSE) { - if (class(phy) != "phylo") + if (!inherits(phy, "phylo")) stop('object "phy" is not of class "phylo"') - ord <- attr(phy, "order") - if (!is.null(ord) && ord == "pruningwise") phy <- reorder(phy) + phy <- reorder(phy) n <- length(phy$tip.label) ROOT <- n + 1 if (!is.null(node)) { @@ -88,7 +86,6 @@ root <- function(phy, outgroup, node = NULL, resolve.root = FALSE) ## First check that the outgroup is monophyletic-- ## unless there's only one tip specified of course if (length(outgroup) > 1) { - msg <- "the specified outgroup is not monophyletic" seq.nod <- .Call("seq_root2tip", phy$edge, n, phy$Nnode, PACKAGE = "ape") sn <- seq.nod[outgroup] @@ -108,9 +105,15 @@ root <- function(phy, outgroup, node = NULL, resolve.root = FALSE) ## (below is slightly faster than calling "bipartition") desc <- which(unlist(lapply(seq.nod, function(x) any(x %in% newroot)))) - if (length(outgroup) != length(desc)) stop(msg) - ## both vectors below are already sorted: - if (!all(outgroup == desc)) stop(msg) + msg <- "the specified outgroup is not monophyletic" + ingroup <- (1:n)[-outgroup] + ## 'outgroup' and 'desc' are already sorted: + if (newroot != ROOT) { + if (!identical(outgroup, desc) && !identical(ingroup, desc)) + stop(msg) + } else { # otherwise check monophyly of the ingroup + if (!is.monophyletic(phy, ingroup)) stop(msg) + } } else newroot <- phy$edge[which(phy$edge[, 2] == outgroup), 1] } N <- Nedge(phy) @@ -128,7 +131,7 @@ root <- function(phy, outgroup, node = NULL, resolve.root = FALSE) if (!is.null(phy$edge.length)) phy$edge.length <- c(phy$edge.length[a], 0, phy$edge.length[b]) - phy$Nnode <- phy$Nnode + 1 + phy$Nnode <- phy$Nnode + 1L ## node renumbering (see comments below) newNb <- integer(n + oldNnode) newNb[newroot] <- n + 1L @@ -294,14 +297,19 @@ root <- function(phy, outgroup, node = NULL, resolve.root = FALSE) phy$edge[, 1] <- newNb[phy$edge[, 1]] if (!is.null(phy$node.label)) { + #browser() newNb <- newNb[-(1:n)] if (fuseRoot) { newNb <- newNb[-1] phy$node.label <- phy$node.label[-1] } phy$node.label <- phy$node.label[order(newNb)] - if (resolve.root) - phy$node.label <- c(phy$node.label[1], NA, phy$node.label[-1]) + if (resolve.root) { + phy$node.label[is.na(phy$node.label)] <- phy$node.label[1] + phy$node.label[1] <- NA + ##phy$node.label <- c(phy$node.label[1], NA, phy$node.label[-1]) + ##phy$node.label <- c("NA", phy$node.label) + } } phy }