# R/tree_distNode.R In fionarhuang/TreeSummarizedExperiment: TreeSummarizedExperiment: a S4 Class for Data with Tree Structures

#### Documented in distNode

```#' Calculate the distance between any two nodes on the tree
#'
#' \code{distNode} is to calculate the distance between any two nodes on
#' a \code{phylo} tree
#'
#' @param tree A phylo object.
#' @param node A numeric or character vector of length two.
#' @export
#' @return A numeric value.
#'
#' @examples
#' library(ggtree)
#' data(tinyTree)
#' ggtree(tinyTree) +
#'     geom_text2(aes(label = node), color = "darkorange",
#'            hjust = -0.1, vjust = -0.7) +
#'     geom_text2(aes(label = branch.length), color = "darkblue",
#'                vjust = 0.7)
#'
#'
#' distNode(tree = tinyTree, node = c(10, 11))
#' distNode(tree = tinyTree, node = c(12, 13))
#' distNode(tree = tinyTree, node = c(13, 15))
#' distNode(tree = tinyTree, node = c(12, 14))

distNode <- function(tree, node) {

if (!inherits(tree, "phylo")) {
stop("tree: should be a phylo object.", call. = FALSE)
}

if (is.character(node)) {
node <- convertNode(tree = tree, node = node)
}

mat <- matTree(tree)
ed <- tree\$edge

oo <- lapply(node, FUN = function(x) {
xx <- which(mat == x, arr.ind = TRUE)
return(xx)
})

samePath <- intersect(oo[[1]][, "row"], oo[[2]][, "row"])
if (length(samePath)) {
dd <- .samePath(tree = tree, node = node)
} else {
dd <- .diffPath(tree = tree, node = node)
}

return(dd)

}

.samePath <- function(tree, node) {
# edges
ed <- tree\$edge

# edge.length
len <- tree\$edge.length

# the input nodes are not directly connected but in the same path
mt <- matTree(tree = tree)
loc <- lapply(node, FUN = function(x) {
xx <- which(mt == x, arr.ind = TRUE)
})

shareRow <- intersect(loc[[1]][, "row"], loc[[2]][, "row"])
ush <- unique(shareRow)[1]

loc <- do.call(rbind, loc)
tcol <- loc[loc[, "row"] == ush, "col"]
sel <- seq(from = max(tcol), to = min(tcol), by = -1)
pn <- mt[ush, sel[-length(sel)]]
cn <- mt[ush, sel[-1]]
pir <- cbind(pn, cn)
fi <- match(data.frame(t(pir)), data.frame(t(ed)))
dd <- sum(len[fi])

return(dd)
}

.diffPath <- function(tree, node) {
# the share node
sNode <- shareNode(tree = tree, node = node)

d1 <- .samePath(tree = tree, node = c(node[1], sNode))
d2 <- .samePath(tree = tree, node = c(node[2], sNode))
dd <- d1 + d2

return(dd)
}
```
fionarhuang/TreeSummarizedExperiment documentation built on Aug. 18, 2021, 12:15 p.m.