CHANGES IN APE VERSION 3.0-6
+NEW FEATURES
+
+ o reorder.phylo() has a new order, "postorder", and a new option
+ index.only = TRUE to return only the vector of indices (the tree
+ is unmodified; see ?reorder.phylo for details).
+
+
+BUG FIXES
+
+ o reorder(, "pruningwise") made R crash if the rows of the edge
+ matrix are in random order.
+
+
OTHER CHANGES
o dist.nodes() is now 6 to 10 times faster.
-## reorder.phylo.R (2012-08-17)
+## reorder.phylo.R (2012-09-03)
## Internal Reordering of Trees
## This file is part of the R-package `ape'.
## See the file ../COPYING for licensing issues.
-reorder.phylo <- function(x, order = "cladewise", ...)
+reorder.phylo <- function(x, order = "cladewise", index.only = FALSE, ...)
{
- order <- match.arg(order, c("cladewise", "pruningwise"))
+ ORDER <- c("cladewise", "postorder", "pruningwise")
+ io <- pmatch(order, ORDER)
+ if (is.na(io)) stop("ambiguous order")
+ order <- ORDER[io]
if (!is.null(attr(x, "order")))
if (attr(x, "order") == order) return(x)
nb.node <- x$Nnode
if (nb.node == 1) return(x)
nb.tip <- length(x$tip.label)
nb.edge <- dim(x$edge)[1]
- if (order == "cladewise") {
- neworder <-
- .C("neworder_cladewise", as.integer(nb.tip),
- as.integer(x$edge[, 1]), as.integer(x$edge[, 2]),
- as.integer(nb.edge), integer(nb.edge),
- DUP = FALSE, NAOK = TRUE, PACKAGE = "ape")[[5]]
- } else {
- ##node.degree <- tabulate(x$edge[, 1])
+ if (io == 3) {
+ x <- reorder(x)
neworder <-
.C("neworder_pruningwise", as.integer(nb.tip),
as.integer(nb.node), as.integer(x$edge[, 1]),
as.integer(x$edge[, 2]), as.integer(nb.edge),
integer(nb.edge), PACKAGE = "ape")[[6]]
+ } else {
+ neworder <-
+ .C("neworder_phylo", as.integer(nb.tip),
+ as.integer(x$edge[, 1]), as.integer(x$edge[, 2]),
+ as.integer(nb.edge), integer(nb.edge), io,
+ DUP = FALSE, NAOK = TRUE, PACKAGE = "ape")[[5]]
}
+ if (index.only) return(neworder)
x$edge <- x$edge[neworder, ]
if (!is.null(x$edge.length))
- x$edge.length <- x$edge.length[neworder]
+ x$edge.length <- x$edge.length[neworder]
attr(x, "order") <- order
x
}
+
the one input, but the ordering of the edges could be different.
}
\usage{
-\method{reorder}{phylo}(x, order = "cladewise", ...)
+\method{reorder}{phylo}(x, order = "cladewise", index.only = FALSE, ...)
}
\arguments{
\item{x}{an object of class \code{"phylo"}.}
\item{order}{a character string: either \code{"cladewise"} (the
- default), or \code{"pruningwise"}, or any unambiguous abbreviation
- of these.}
+ default), \code{"postorder"}, \code{"pruningwise"}, or any
+ unambiguous abbreviation of these.}
+ \item{index.only}{should the function return only the ordered indices
+ of the rows of the edge matrix?}
\item{\dots}{further arguments passed to or from other methods.}
}
\details{
multichotomies and branch lengths are preserved.
}
\value{
- an object of class \code{"phylo"}.
+ an object of class \code{"phylo"}, or a numeric vector if \code{index.only = TRUE}.
}
\author{Emmanuel Paradis}
\seealso{
-/* reorder_phylo.c 2012-08-17 */
+/* reorder_phylo.c 2012-09-03 */
/* Copyright 2008-2012 Emmanuel Paradis */
}
}
-void neworder_cladewise(int *n, int *e1, int *e2, int *N, int *neworder)
+void bar_reorder(int node, int n, int m, int *e1, int *e2, int *neworder, int *L, int *pos)
+{
+ int i = node - n - 1, j, k;
+
+ for (j = pos[i] - 1; j >= 0; j--)
+ neworder[iii--] = L[i + m * j] + 1;
+
+ for (j = 0; j < pos[i]; j++) {
+ k = e2[L[i + m * j]];
+ if (k > n)
+ bar_reorder(k, n, m, e1, e2, neworder, L, pos);
+ }
+}
+
+void neworder_phylo(int *n, int *e1, int *e2, int *N, int *neworder, int *order)
/* n: nb of tips
m: nb of nodes
N: nb of edges */
/* We start with the root 'n + 1': its index will be changed into
the corresponding C index inside the recursive function. */
- iii = 0;
- foo_reorder(*n + 1, *n, m, e1, e2, neworder, L, pos);
+ switch(*order) {
+ case 1 : iii = 0;
+ foo_reorder(*n + 1, *n, m, e1, e2, neworder, L, pos);
+ break;
+ case 2 : iii = *N - 1;
+ bar_reorder(*n + 1, *n, m, e1, e2, neworder, L, pos);
+ break;
+ }
}
-
#define DO_NODE_PRUNING\
/* go back down in `edge' to set `neworder' */\
for (j = 0; j <= i; j++) {\
nextI++;
}
}
+