dendrapply | R Documentation |
Apply function FUN to each node of a dendrogram recursively. When y <- dendrapply(x, fn), then y is a dendrogram of the same graph structure as x and for each node, y.node[j] <- FUN( x.node[j], ...) (where y.node[j] is an (invalid!) notation for the j-th node of y). Also provides flexibility in the order in which nodes are evaluated.
NOTE: This man page is for the dendrapply
function defined in the SynExtend package. See ?stats::dendrapply
for the default method (defined in the stats package).
dendrapply(X, FUN, ...,
how = c("pre.order", "post.order"))
X |
An object of class |
FUN |
An R function to be applied to each dendrogram node, typically working on its |
... |
potential further arguments passed to |
how |
one of |
"pre.order"
preserves the functionality of the previous dendrapply
. For each node n
, FUN
is applied first to n
, then to n[[1]]
(and any children it may have), then n[[2]]
and its children, etc. Notably, each node is evaluted prior to any of its children.
"post.order"
allows for calculations that depend on the children of a given node. For each node n
, FUN
is applied first to all children of n
, then is applied to n
itself. Notably, each node is evaluated after all of its children.
Usually a dendrogram of the same (graph) structure as X
. For that, the function must be conceptually of the form FUN <- function(X) { attributes(X) <- .....; X }
, i.e., returning the node with some attributes added or changed.
If the function provided does not return the node, the result is a nested list of the same structure as X
, or as close as can be achieved with the return values. If the function should only be applied to the leaves of X
, consider using rapply
instead.
dendrapply
identifies leaf nodes as nodes such that attr(node, 'leaf') == TRUE
, and internal nodes as nodes such that attr(node, 'leaf') %in% c(NULL, FALSE)
. If you modify or remove this attribute, dendrapply
may perform unexpectedly.
The prior implementation of dendrapply
was recursive and inefficient for dendrograms with many non-leaves. This version is no longer recursive, and thus should no longer cause issues stemming from insufficient C stack size (as mentioned in the 'Warning' in dendrogram
).
Aidan Lakshman ahl27@pitt.edu
as.dendrogram
, lapply
for applying a function to each component of a list.
rapply
is particularly useful for applying a function to the leaves of a dendrogram, and almost always be used when the function does not need to be applied to interior nodes due to significantly better performance.
require(graphics)
## a smallish simple dendrogram
dhc <- as.dendrogram(hc <- hclust(dist(USArrests), "ave"))
(dhc21 <- dhc[[2]][[1]])
## too simple:
dendrapply(dhc21, function(n) utils::str(attributes(n)))
## toy example to set colored leaf labels :
local({
colLab <<- function(n) {
if(is.leaf(n)) {
a <- attributes(n)
i <<- i+1
attr(n, "nodePar") <- c(a$nodePar, list(lab.col = mycols[i], lab.font = i%%3))
}
n
}
mycols <- grDevices::rainbow(attr(dhc21,"members"))
i <- 0
})
dL <- dendrapply(dhc21, colLab)
op <- par(mfrow = 2:1)
plot(dhc21)
plot(dL) ## --> colored labels!
par(op)
## Illustrating difference between pre.order and post.order
dend <- as.dendrogram(hclust(dist(seq_len(4L))))
f <- function(x){
if(!is.null(attr(x, 'leaf'))){
v <- as.character(attr(x, 'label'))
} else {
v <- paste0(attr(x[[1]], 'newattr'), attr(x[[2]], 'newattr'))
}
attr(x, 'newattr') <- v
x
}
# trying with default, note character(0) entries
preorder_try <- dendrapply(dend, f)
dendrapply(preorder_try, \(x){ print(attr(x, 'newattr')); x })
## trying with postorder, note that children nodes will already
## have been populated, so no character(0) entries
postorder_try <- dendrapply(dend, f, how='post.order')
dendrapply(postorder_try, \(x){ print(attr(x, 'newattr')); x })
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.