[R] no labels when plotting dendrograms

Wiener, Matthew matthew_wiener at merck.com
Tue Mar 5 14:52:27 CET 2002


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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._



More information about the R-help mailing list