Nothing
#' Match nodes and edges between trees
#'
#' `MatchNodes()` and `MatchEdges()` matches nodes or edges in one tree to
#' entries in the second that denote a clade with identical tip labels.
#'
#' The current implementation is potentially inefficient.
#' Please contact the maintainer to request a more efficient implementation if
#' this function is proving a bottleneck.
#'
#' @param x Tree whose nodes are to be matched.
#' @param table Tree containing nodes to be matched against.
#' @param tips Logical specifying whether to return matches for tips;
#' unless `TRUE`, only the matches for internal nodes will be returned.
#' @examples
#' MatchNodes(BalancedTree(8), RootTree(BalancedTree(8)))
#' @inheritParams match
#' @template MRS
#' @family tree navigation
#' @family tree properties
#' @export
MatchEdges <- function(x, table, nomatch = NA_integer_) {
xEdge <- .Edge(x)
tableEdge <- .Edge(table)
xLab <- TipLabels(x)
tabLab <- TipLabels(table)
tipMatch <- if (is.null(xLab) && is.null(tabLab)) {
# Match tips by number
xTip <- min(xEdge[, 1]) - 1
tabTip <- min(tableEdge[, 1]) - 1
`length<-`(seq_len(tabTip), xTip)
} else {
match(xLab, tabLab)
}
seek <- DescendantTips(xEdge[, 1], xEdge[, 2])
find <- DescendantTips(tableEdge[, 1], tableEdge[, 2])[, tipMatch]
find[is.na(find)] <- FALSE
match(as.data.frame(t(seek)), as.data.frame(t(find)))
}
.Edge <- function(x) {
UseMethod(".Edge")
}
#' @export
.Edge.phylo <- function(x) {
x[["edge"]]
}
#' @export
.Edge.numeric <- function(x) {
x
}
#' @export
.Edge.list <- function(x) {
if (is.null(x[["edge"]])) {
cbind(x[[1]], x[[2]])
} else {
x[["edge"]]
}
}
#' @rdname MatchEdges
#' @export
MatchNodes <- function(x, table, nomatch = NA_integer_, tips = FALSE) {
xEdge <- .Edge(x)
xLab <- TipLabels(x)
tableEdge <- .Edge(table)
tabLab <- TipLabels(table)
allLab <- union(xLab, tabLab)
tipMatch <- match(xLab, tabLab)
seek <- DescendantTips(xEdge[, 1], xEdge[, 2])[, match(allLab, xLab)]
seek[is.na(seek)] <- FALSE
find <- DescendantTips(tableEdge[, 1], tableEdge[, 2])[, match(allLab, tabLab)]
find[is.na(find)] <- FALSE
findFrame <-as.data.frame(cbind(t(find), allLab %in% tabLab),
optional = TRUE)
matching <- match(as.data.frame(t(seek), optional = TRUE), findFrame)
matchRoot <- match(as.data.frame(allLab %in% xLab, optional = TRUE),
findFrame)
nodeIndex <- c(tableEdge[, 2], length(tabLab) + 1)
xRoot <- length(xLab) + 1L
ret <- nodeIndex[matching][order(c(xEdge[, 2], xRoot))]
ret[xRoot] <- nodeIndex[matchRoot]
if (!isTRUE(tips)) {
ret <- ret[-seq_along(xLab)]
}
# Return:
`[<-`(ret, is.na(ret), nomatch)
}
.UpdateNodeLabel <- function(new, old, nodeLabel = old[["node.label"]], ...) {
UseMethod(".UpdateNodeLabel")
}
#' @export
.UpdateNodeLabel.numeric <- function(new, old, nodeLabel = old[["node.label"]],
newTips = TipLabels(old), ...) {
nodeLabel[MatchNodes(list(edge = new, tip.label = newTips),
old, tips = FALSE) - NTip(old)]
}
#' @export
.UpdateNodeLabel.phylo <- function(new, old, nodeLabel = old[["node.label"]], ...) {
nodeLabel[MatchNodes(new, old, tips = FALSE) - NTip(old)]
}
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.