The R Project SVN R

Rev

Rev 69446 | Rev 80080 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
42333 ripley 1
% File src/library/stats/man/dendrogram.Rd
68948 ripley 2
% Part of the R package, https://www.R-project.org
70613 maechler 3
% Copyright 1995-2016 R Core Team
68633 maechler 4
% Copyright 2002-2015 The R Foundation
42333 ripley 5
% Distributed under GPL 2 or later
6
 
27474 ripley 7
\name{dendrogram}
8
\title{General Tree Structures}
56186 murdoch 9
\alias{dendrogram}% the class
27474 ripley 10
\alias{as.dendrogram}
41244 ripley 11
\alias{as.dendrogram.dendrogram}
29701 maechler 12
\alias{as.dendrogram.hclust}
53892 maechler 13
\alias{as.hclust.dendrogram}
27474 ripley 14
\alias{cut.dendrogram}
15
\alias{[[.dendrogram}
53892 maechler 16
\alias{merge.dendrogram}
66629 maechler 17
\alias{nobs.dendrogram}
53892 maechler 18
\alias{plot.dendrogram}
27474 ripley 19
\alias{print.dendrogram}
20
\alias{rev.dendrogram}
21
\alias{str.dendrogram}
30228 maechler 22
\alias{is.leaf}
27474 ripley 23
\description{
24
  Class \code{"dendrogram"} provides general functions for handling
25
  tree-like structures.  It is intended as a replacement for similar
26
  functions in hierarchical clustering and classification/regression
27
  trees, such that all of these can use the same engine for plotting or
28
  cutting trees.
29
}
30
\usage{
31
as.dendrogram(object, \dots)
66839 maechler 32
\method{as.dendrogram}{hclust}(object, hang = -1, check = TRUE, \dots)
27474 ripley 33
 
53892 maechler 34
\method{as.hclust}{dendrogram}(x, \dots)
35
 
27474 ripley 36
\method{plot}{dendrogram}(x, type = c("rectangle", "triangle"),
30912 ripley 37
      center = FALSE,
38
      edge.root = is.leaf(x) || !is.null(attr(x,"edgetext")),
30884 maechler 39
      nodePar = NULL, edgePar = list(),
30912 ripley 40
      leaflab = c("perpendicular", "textlike", "none"),
41
      dLeaf = NULL, xlab = "", ylab = "", xaxt = "n", yaxt = "s",
46113 maechler 42
      horiz = FALSE, frame.plot = FALSE, xlim, ylim, \dots)
27474 ripley 43
 
44
\method{cut}{dendrogram}(x, h, \dots)
45
 
66648 maechler 46
\method{merge}{dendrogram}(x, y, \dots, height,
66655 maechler 47
      adjust = c("auto", "add.max", "none"))
53892 maechler 48
 
66631 maechler 49
\method{nobs}{dendrogram}(object, \dots)
66629 maechler 50
 
27474 ripley 51
\method{print}{dendrogram}(x, digits, \dots)
52
 
53
\method{rev}{dendrogram}(x)
54
 
40832 maechler 55
\method{str}{dendrogram}(object, max.level = NA, digits.d = 3,
27474 ripley 56
    give.attr = FALSE, wid = getOption("width"),
57963 maechler 57
    nest.lev = 0, indent.str = "",
58
    last.str = getOption("str.dendrogram.last"), stem = "--",
56287 ripley 59
    \dots)
30228 maechler 60
 
61
is.leaf(object)
27474 ripley 62
}
63
\arguments{
64
  \item{object}{any \R object that can be made into one of class
65
    \code{"dendrogram"}.}
60892 ripley 66
  \item{x, y}{object(s) of class \code{"dendrogram"}.}
29701 maechler 67
  \item{hang}{numeric scalar indicating how the \emph{height} of leaves
68
    should be computed from the heights of their parents; see
69
    \code{\link{plot.hclust}}.}
66839 maechler 70
  \item{check}{logical indicating if \code{object} should be checked for
71
    validity.  This check is not necessary when \code{x} is known to be
72
    valid such as when it is the direct result of \code{hclust()}.  The
69446 ripley 73
    default is \code{check=TRUE}, e.g.\sspace{}for protecting against memory
66839 maechler 74
    explosion with invalid inputs.}
27474 ripley 75
  \item{type}{type of plot.}
76
  \item{center}{logical; if \code{TRUE}, nodes are plotted centered with
77
    respect to the leaves in the branch.  Otherwise (default), plot them
78
    in the middle of all direct child nodes.}
79
  \item{edge.root}{logical; if true, draw an edge to the root node.}
80
  \item{nodePar}{a \code{list} of plotting parameters to use for the
81
    nodes (see \code{\link{points}}) or \code{NULL} by default which
82
    does not draw symbols at the nodes.  The list may contain components
54147 maechler 83
    named \code{pch}, \code{cex}, \code{col}, \code{xpd},
84
    and/or \code{bg} each of
27474 ripley 85
    which can have length two for specifying separate attributes for
54147 maechler 86
    \emph{inner} nodes and \emph{leaves}.  Note that the default of
87
    \code{pch} is \code{1:2}, so you may want to use \code{pch = NA} if
88
    you specify \code{nodePar}.}
27474 ripley 89
  \item{edgePar}{a \code{list} of plotting parameters to use for the
30228 maechler 90
    edge \code{\link{segments}} and labels (if there's an
91
    \code{edgetext}).  The list may contain components
92
    named \code{col}, \code{lty} and \code{lwd} (for the segments),
93
    \code{p.col}, \code{p.lwd}, and \code{p.lty} (for the
94
    \code{\link{polygon}} around the text) and \code{t.col} for the text
95
    color.  As with \code{nodePar}, each can have length two for
96
    differentiating leaves and inner nodes.
97
  }
30884 maechler 98
  \item{leaflab}{a string specifying how leaves are labeled.  The
99
    default \code{"perpendicular"} write text vertically (by default).\cr
100
    \code{"textlike"} writes text horizontally (in a rectangle), and \cr
101
    \code{"none"} suppresses leaf labels.}
102
  \item{dLeaf}{a number specifying the \bold{d}istance in user
103
    coordinates between the tip of a leaf and its label.  If \code{NULL}
104
    as per default, 3/4 of a letter width or height is used.}
105
  \item{horiz}{logical indicating if the dendrogram should be drawn
27474 ripley 106
    \emph{horizontally} or not.}
107
  \item{frame.plot}{logical indicating if a box around the plot should
108
    be drawn, see \code{\link{plot.default}}.}
109
  \item{h}{height at which the tree is cut.}
66629 maechler 110
  \item{height}{height at which the two dendrograms should be merged.  If not
53892 maechler 111
    specified (or \code{NULL}), the default is ten percent larger than
112
    the (larger of the) two component heights.}
66648 maechler 113
  \item{adjust}{a string determining if the leaf values should be
114
    adjusted.  The default, \code{"auto"}, checks if the (first) two
115
    dendrograms both start at \code{1}; if they do, code{"add.max"} is
116
    chosen, which adds the maximum of the previous dendrogram leaf
117
    values to each leaf of the \dQuote{next} dendrogram.  Specifying
118
    \code{adjust} to another value skips the check and hence is a tad
119
    more efficient.}
46113 maechler 120
  \item{xlim, ylim}{optional x- and y-limits of the plot, passed to
121
    \code{\link{plot.default}}.  The defaults for these show the full
122
    dendrogram.}
30884 maechler 123
  \item{\dots, xlab, ylab, xaxt, yaxt}{graphical parameters, or arguments for
27474 ripley 124
    other methods.}
40281 ripley 125
  \item{digits}{integer specifying the precision for printing, see
27474 ripley 126
    \code{\link{print.default}}.}
50092 ripley 127
  \item{max.level, digits.d, give.attr, wid, nest.lev, indent.str}{arguments
128
    to \code{str}, see \code{\link{str.default}()}.  Note that
30884 maechler 129
    \code{give.attr = FALSE} still shows \code{height} and \code{members}
130
    attributes for each node.}
53892 maechler 131
  \item{last.str, stem}{strings used for \code{str()} specifying how the
132
    last branch (at each level) should start and the \emph{stem}
57963 maechler 133
    to use for each dendrogram branch.  In some environments, using
134
    \code{last.str = "'"} will provide much nicer looking output, than
135
    the historical default \code{last.str = "`"}.}
27474 ripley 136
}
137
\details{
138
  The dendrogram is directly represented as a nested list where each
139
  component corresponds to a branch of the tree.  Hence, the first
140
  branch of tree \code{z} is \code{z[[1]]}, the second branch of the
53892 maechler 141
  corresponding subtree is \code{z[[1]][[2]]}, or shorter
142
  \code{z[[c(1,2)]]}, etc..  Each node of the tree
27474 ripley 143
  carries some information needed for efficient plotting or cutting as
30228 maechler 144
  attributes, of which only \code{members}, \code{height} and
145
  \code{leaf} for leaves are compulsory:
27474 ripley 146
  \describe{
147
    \item{\code{members}}{total number of leaves in the branch}
148
    \item{\code{height}}{numeric non-negative height at which the node
149
      is plotted.}
150
    \item{\code{midpoint}}{numeric horizontal distance of the node from
29796 maechler 151
      the left border (the leftmost leaf) of the branch (unit 1 between
61160 ripley 152
      all leaves).  This is used for \code{plot(*, center = FALSE)}.}
27474 ripley 153
    \item{\code{label}}{character; the label of the node}
30228 maechler 154
    \item{\code{x.member}}{for \code{cut()$upper},
155
      the number of \emph{former} members; more generally a substitute
42961 ripley 156
      for the \code{members} component used for \sQuote{horizontal}
157
      (when \code{horiz = FALSE}, else \sQuote{vertical}) alignment.}
27474 ripley 158
    \item{\code{edgetext}}{character; the label for the edge leading to
159
      the node}
30228 maechler 160
    \item{\code{nodePar}}{a named list (of length-1 components)
161
      specifying node-specific attributes for \code{\link{points}}
162
      plotting, see the \code{nodePar} argument above.}
163
    \item{\code{edgePar}}{a named list (of length-1 components)
164
      specifying attributes for \code{\link{segments}} plotting of the
165
      edge leading to the node, and drawing of the \code{edgetext} if
166
      available, see the \code{edgePar} argument above.}
27474 ripley 167
    \item{\code{leaf}}{logical, if \code{TRUE}, the node is a leaf of
168
      the tree.}%  This will often be a \code{\link{character}} which can
169
    %      be used for plotting instead of the \code{text} attribute.}
170
  }
171
 
172
  \code{cut.dendrogram()} returns a list with components \code{$upper}
173
  and \code{$lower}, the first is a truncated version of the original
174
  tree, also of class \code{dendrogram}, the latter a list with the
175
  branches obtained from cutting the tree, each a \code{dendrogram}.
176
 
177
  There are \code{\link{[[}}, \code{\link{print}}, and \code{\link{str}}
178
  methods for \code{"dendrogram"} objects where the first one
65131 maechler 179
  (extraction) ensures that selecting sub-branches keeps the class,
180
  i.e., returns a dendrogram even if only a leaf.
181
  On the other hand, \code{\link{[}} (\emph{single} bracket) extraction
182
  returns the underlying list structure.%, useful, e.g., for inspection.
27474 ripley 183
 
184
  Objects of class \code{"hclust"} can be converted to class
53892 maechler 185
  \code{"dendrogram"} using method \code{as.dendrogram()}, and since R
186
  2.13.0, there is also a \code{\link{as.hclust}()} method as an inverse.
27474 ripley 187
 
29799 maechler 188
  \code{rev.dendrogram} simply returns the dendrogram \code{x} with
189
  reversed nodes, see also \code{\link{reorder.dendrogram}}.
190
 
66629 maechler 191
  The \code{\link{merge}(x, y, ...)} method merges two or more
53892 maechler 192
  dendrograms into a new one which has \code{x} and \code{y} (and
66648 maechler 193
  optional further arguments) as branches.  Note that before \R 3.1.2,
194
  \code{adjust = "none"} was used implicitly, which is invalid when,
195
  e.g., the dendrograms are from \code{\link{as.dendrogram}(hclust(..))}.
53892 maechler 196
 
66629 maechler 197
  \code{\link{nobs}(object)} returns the total number of leaves (the
66631 maechler 198
  \code{members} attribute, see above).
66629 maechler 199
 
60892 ripley 200
  \code{is.leaf(object)} returns logical indicating if \code{object} is a
30228 maechler 201
  leaf (the most simple dendrogram).
60892 ripley 202
 
30228 maechler 203
  \code{plotNode()} and \code{plotNodeLimit()} are helper functions.
27474 ripley 204
}
205
\note{
53892 maechler 206
  \describe{
207
    \item{\code{plot()}:}{When using \code{type = "triangle"},
208
      \code{center = TRUE} often looks better.}
209
    \item{\code{str(d)}:}{If you really want to see the \emph{internal}
210
      structure, use \code{str(unclass(d))} instead.}
211
  }
27474 ripley 212
}
35940 ripley 213
\section{Warning}{
68633 maechler 214
  Some operations on dendrograms such as \code{merge()} make use of
70613 maechler 215
  recursion.  For deep trees it may be necessary to increase
216
  \code{\link{options}("expressions")}: if you do, you are likely to need
217
  to set the C stack size (\code{\link{Cstack_info}()[["size"]]}) larger
218
  than the default where possible.
35940 ripley 219
}
30228 maechler 220
\seealso{
53892 maechler 221
  \code{\link{dendrapply}} for applying a function to \emph{each} node.
222
  \code{\link{order.dendrogram}} and \code{\link{reorder.dendrogram}};
223
  further, the \code{\link{labels}} method.
30228 maechler 224
}
27474 ripley 225
\examples{
41508 ripley 226
require(graphics); require(utils)
227
 
27474 ripley 228
hc <- hclust(dist(USArrests), "ave")
229
(dend1 <- as.dendrogram(hc)) # "print()" method
30884 maechler 230
str(dend1)          # "str()" method
61160 ripley 231
str(dend1, max = 2, last.str =  "'") # only the first two sub-levels
57963 maechler 232
oo <- options(str.dendrogram.last = "\\\\") # yet another possibility
233
str(dend1, max = 2) # only the first two sub-levels
61168 ripley 234
options(oo)  # .. resetting them
27474 ripley 235
 
61160 ripley 236
op <- par(mfrow =  c(2,2), mar = c(5,2,1,4))
27474 ripley 237
plot(dend1)
238
## "triangle" type and show inner nodes:
61160 ripley 239
plot(dend1, nodePar = list(pch = c(1,NA), cex = 0.8, lab.cex = 0.8),
240
      type = "t", center = TRUE)
241
plot(dend1, edgePar = list(col = 1:2, lty = 2:3),
242
     dLeaf = 1, edge.root = TRUE)
243
plot(dend1, nodePar = list(pch = 2:1, cex = .4*2:1, col = 2:3),
244
     horiz = TRUE)
27474 ripley 245
 
54147 maechler 246
## simple test for as.hclust() as the inverse of as.dendrogram():
53892 maechler 247
stopifnot(identical(as.hclust(dend1)[1:4], hc[1:4]))
248
 
61160 ripley 249
dend2 <- cut(dend1, h = 70)
27474 ripley 250
plot(dend2$upper)
49649 ripley 251
## leaves are wrong horizontally:
61160 ripley 252
plot(dend2$upper, nodePar = list(pch = c(1,7), col = 2:1))
27474 ripley 253
##  dend2$lower is *NOT* a dendrogram, but a list of .. :
61160 ripley 254
plot(dend2$lower[[3]], nodePar = list(col = 4), horiz = TRUE, type = "tr")
27474 ripley 255
## "inner" and "leaf" edges in different type & color :
61168 ripley 256
plot(dend2$lower[[2]], nodePar = list(col = 1),   # non empty list
61160 ripley 257
     edgePar = list(lty = 1:2, col = 2:1), edge.root = TRUE)
27474 ripley 258
par(op)
53892 maechler 259
d3 <- dend2$lower[[2]][[2]][[1]]
260
stopifnot(identical(d3, dend2$lower[[2]][[c(2,1)]]))
61160 ripley 261
str(d3, last.str = "'")
30228 maechler 262
 
66629 maechler 263
## to peek at the inner structure "if you must", use '[..]' indexing :
65131 maechler 264
str(d3[2][[1]]) ## or the full
265
str(d3[])
266
 
53892 maechler 267
## merge() to join dendrograms:
268
(d13 <- merge(dend2$lower[[1]], dend2$lower[[3]]))
269
## merge() all parts back (using default 'height' instead of original one):
270
den.1 <- Reduce(merge, dend2$lower)
271
## or merge() all four parts at same height --> 4 branches (!)
56287 ripley 272
d. <- merge(dend2$lower[[1]], dend2$lower[[2]], dend2$lower[[3]],
273
            dend2$lower[[4]])
53892 maechler 274
## (with a warning) or the same using  do.call :
275
stopifnot(identical(d., do.call(merge, dend2$lower)))
61160 ripley 276
plot(d., main = "merge(d1, d2, d3, d4)  |->  dendrogram with a 4-split")
53892 maechler 277
 
46113 maechler 278
## "Zoom" in to the first dendrogram :
279
plot(dend1, xlim = c(1,20), ylim = c(1,50))
280
 
61160 ripley 281
nP <- list(col = 3:2, cex = c(2.0, 0.75), pch =  21:22,
282
           bg =  c("light blue", "pink"),
30228 maechler 283
           lab.cex = 0.75, lab.col = "tomato")
61160 ripley 284
plot(d3, nodePar= nP, edgePar = list(col = "gray", lwd = 2), horiz = TRUE)
30228 maechler 285
%% now add some "edgetext" :
286
addE <- function(n) {
287
      if(!is.leaf(n)) {
61160 ripley 288
        attr(n, "edgePar") <- list(p.col = "plum")
30228 maechler 289
        attr(n, "edgetext") <- paste(attr(n,"members"),"members")
290
      }
291
      n
27474 ripley 292
}
30228 maechler 293
d3e <- dendrapply(d3, addE)
61160 ripley 294
plot(d3e, nodePar =  nP)
295
plot(d3e, nodePar =  nP, leaflab = "textlike")
30228 maechler 296
 
61160 ripley 297
%% BUG:  edge labeling *and* leaflab = "textlike" both fail with  horiz = TRUE:
298
%% BUG plot(d3e, nodePar = nP, leaflab = "textlike", horiz = TRUE)
30228 maechler 299
}
27474 ripley 300
\keyword{multivariate}
301
\keyword{tree}% FIXME: want as.dendrogram.tree() etc!
302
\keyword{hplot}% only for plot.()