David -- I recently posted some code to extract subtrees of hclust objects.
It's included below. As usual, although I believe this code to work and
have used it myself, it comes with no guarantees.
Hope it helps,
Matt Wiener
----------------------------------------------------------------------------
------
"f.get.subtrees" <-
function(tree, k = NULL, h = NULL,
add.element = NULL){
## tree is a tree, k and h are as in cutree.
## additional elements is the name of any additional info
## connected with tree nodes. The additional elements referred
## to should have the same length as tree$labels.
##
groups <- cutree(tree, k, h)
subtrees <- list()
for(i in 1:length(unique(groups))){
subtrees[[i]] <- f.make.subtree(tree, groups, i,
add.element = add.element)
}
subtrees
}
"f.make.subtree" <-
function (tree, groups, n = 1, add.element = NULL)
{
which.nodes <- which(groups == n)
names(which.nodes) <- NULL
## steal some code from plot.hclust
use.labels <-
if (is.null(tree$labels))
paste(1:(nrow(tree$merge) + 1))
else as.character(tree$labels)
subtree.labels <- use.labels[which.nodes]
subtree.order <- tree$order[use.labels[tree$order] %in%
subtree.labels]
which.merge.elements <- which(-tree$merge %in% which.nodes)
which.merge.rows <- sort(unique(which.merge.elements%%nrow(tree$merge)))
which.merge.rows[which.merge.rows == 0] <- nrow(tree$merge)
old.length <- 0
new.length <- length(which.merge.rows)
if (length(which.merge.elements) == 1) {
res <- list(merge = NULL, heights = tree$height[which.merge.rows],
order = 1,
labels = {if(is.null(tree$labels)) NULL else
subtree.labels},
method = tree$method,
call = tree$call, dist.method = tree$dist.method)
}
else {
while (new.length - old.length > 0) {
old.length <- new.length
new.rows <- numeric(0)
more.new.rows <- numeric(0)
row.elements <- as.vector(tree$merge[which.merge.rows,
])
pos.elements <- row.elements[row.elements > 0]
if (length(pos.elements) > 0)
new.rows <- pos.elements[apply(tree$merge[pos.elements,
, drop = F], 1,
function(x) {
any(x > 0) & all(-x[x
<
0] %in% which.nodes)
})]
more.new.rows <- which(apply(tree$merge, 1, function(x) {
all(x %in% which.merge.rows)
}))
which.merge.rows <- sort(unique(c(which.merge.rows,
new.rows, more.new.rows)))
new.length <- length(which.merge.rows)
}
merge.list <- tree$merge[which.merge.rows, , drop = F]
merge.height <- tree$height[which.merge.rows]
pos.elements <- sort(merge.list[merge.list > 0])
for (i in seq(along = pos.elements)) merge.list[merge.list =
pos.elements[i]] <- which(pos.elements[i] =which.merge.rows)
neg.elements <- merge.list[merge.list < 0]
minus.neg.elements <- -neg.elements
num.elements <- length(neg.elements)
change.table <- cbind(sort(minus.neg.elements), 1:num.elements)
for (i in 1:num.elements) {
merge.list[merge.list == -change.table[i, 1]] <- -change.table[i,
2]
}
old.order <- subtree.order
subtree.order <- match(use.labels[old.order], subtree.labels)
res <- list(merge = merge.list, height = merge.height,
order = subtree.order,
labels = {if(is.null(tree$labels)) NULL else
subtree.labels},
method = tree$method,
call = list(match.call(), tree$call), dist.method
tree$dist.method)
class(res) <- "hclust"
for (i in seq(along = add.element)) {
res[[add.element[i]]] <- tree[[add.element[i]]][which.nodes]
}
}
res
}
-----Original Message-----
From: David Marimont [mailto:marimont at nxpdata.com]
Sent: Monday, March 04, 2002 11:01 PM
To: R-help at stat.math.ethz.ch
Subject: [R] no labels when plotting dendrograms
I'd like to be able to cut dendrograms at a height I specify
and then plot the resulting subtrees. I wanted to use the
dendrogram object for this purpose because there doesn't seem
to be a canned way to cut a hclust object and get a list of
hclust objects, but there is a function (cut) that does that
for dendrograms. The problem I'm having is that when I plot
a dendrogram, I can't figure out how to add labels to the nodes.
For example, this example from the dendrogram documentation
plots a dendrogram without labels:
library(mva)
data(USArrests)
hc <- hclust(dist(USArrests), "ave")
str(dend1 <- as.dendrogram(hc))
plot(dend1)
dend2 <- cut(dend1, h=70)
plot(dend2$upper)
plot(dend2$lower[[3]])
So... does anyone know how to cut an hclust object and get a
list of hclust objects, or how to plot a dendrogram object with
labels? Thanks.
David Marimont
NXP Data Analysis, Inc.
http://www.nxpdata.com
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-help-request at
stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._