Hierarchical Clustering in R: Dendrograms, Agglomerative & Divisive
Build a tree of nested clusters with hclust(), agnes() and diana() — compare linkage methods with the agglomerative coefficient, read the dendrogram, and cut it into groups
Machine Learning
Hierarchical clustering in R, step by step. Compute the distance matrix, build the cluster tree with hclust() and agnes(), compare linkage methods (complete, average, single, Ward) with the agglomerative coefficient, draw a publication-ready dendrogram with fviz_dend(), cut it into groups with cutree(), and check the fit with the cophenetic correlation. Includes divisive clustering (DIANA) and when to use each.
Published
June 24, 2026
Modified
July 7, 2026
TipKey takeaways
Hierarchical clustering builds a tree of nested clusters (a dendrogram) — and, unlike k-means, you don’t pre-specify the number of clusters: you read it off the tree afterwards.
Agglomerative (bottom-up, AGNES) starts with each observation as its own cluster and merges the closest pair at each step; divisive (top-down, DIANA) starts with one big cluster and splits it.
The result depends on two choices: the distance between observations (dist()) and the linkage rule for the distance between clusters — complete, average, single, or Ward’s (ward.D2).
Use agnes()’s agglomerative coefficient to compare linkage methods objectively — higher is a stronger clustering structure (Ward usually wins).
Draw the tree with fviz_dend(), cut it into groups with cutree(), and check the fit with the cophenetic correlation (above 0.75 is good).
Say you have crime statistics for the 50 US states and you want to find groups of states that behave alike — without deciding up front how many groups there are. Hierarchical clustering (also called hierarchical cluster analysis, or HCA) is built for exactly this. Instead of forcing the data into a fixed number of clusters the way k-means does, it produces a tree — a dendrogram — that shows how observations merge into clusters at every level of similarity. You then cut the tree wherever the grouping makes sense.
This is the method of choice when:
you don’t know how many clusters to expect (the tree shows you the structure at every scale),
you want a visual, interpretable map of how observations relate, or
your data is small to medium (the distance matrix grows fast — hierarchical clustering is not for millions of rows; use k-means or CLARA there).
Hierarchical clustering comes in two flavours:
Agglomerative (bottom-up, AGNES — Agglomerative Nesting): each observation starts as its own cluster; at every step the two most similar clusters are merged, until one big cluster remains. Good at finding small clusters.
Divisive (top-down, DIANA — DIvisive ANAlysis): everything starts in one cluster, which is split again and again until every observation stands alone. Good at finding large clusters.
We focus on agglomerative clustering (the common case), then cover divisive at the end. The four steps are always the same: prepare the data → compute a distance matrix → link into a tree → cut the tree into groups.
The data
We use R’s built-in USArrests dataset — arrests per 100,000 residents for Murder, Assault and Rape, plus the percent UrbanPop, for each US state. The variables are on very different scales, so we standardize them first with scale() (z-scores): otherwise Assault (hundreds) would dominate Murder (single digits) purely because of its units.
# Load the datadata("USArrests")# Standardize: every variable to mean 0, sd 1 (so scales are comparable)df <-scale(USArrests)# First 6 rows of the standardized datahead(df, 6)
Standardizing before clustering is almost always the right call when variables are measured in different units. The distance measures lesson covers when (and how) to standardize in detail.
Step 1 — the distance matrix
Every clustering method needs a rule for how far apart two observations are. The base function dist() computes that for every pair of rows. By default it uses the Euclidean distance; you can switch with method = ("manhattan", "maximum", …) — see the distance measures lesson.
df <-scale(USArrests)# Dissimilarity matrix (Euclidean distance between every pair of states)res.dist <-dist(df, method ="euclidean")# Peek at the first 6×6 corner of the matrixas.matrix(res.dist)[1:6, 1:6]
Read the matrix like a mileage chart: the cell at row i, column j is the distance between state i and state j. The diagonal is zero (every state’s distance to itself), and the matrix is symmetric.
Step 2 — agglomerative clustering with hclust()
The base function hclust() takes the distance matrix and links observations into a tree. The key argument is method =, the linkage rule — how to measure the distance between two clusters (not just two points):
df <-scale(USArrests)res.dist <-dist(df, method ="euclidean")# Build the hierarchical tree using Ward's methodres.hc <-hclust(d = res.dist, method ="ward.D2")
Which linkage method?
Linkage is the one choice that most changes the shape of the tree. The common rules:
Complete (maximum) linkage — distance between clusters = the largest pairwise distance. Tends to produce compact, tight clusters.
Single (minimum) linkage — the smallest pairwise distance. Tends to produce long, straggly “chained” clusters (one outlier can stretch a cluster).
Average linkage — the average of all pairwise distances. A middle ground.
Centroid linkage — distance between the two cluster centroids (mean vectors).
Ward’s minimum variance (ward.D2) — at each step merges the pair that increases the total within-cluster variance the least. Produces balanced, roughly equal-sized, compact clusters.
Tip
Complete linkage and Ward’s method are the usual defaults — they give compact, interpretable clusters. Single linkage is rarely what you want for grouping (it chains), but it is good at spotting outliers. We use ward.D2 here. (Use ward.D2, notward.D — see Common issues.)
Compare linkage methods objectively: the agglomerative coefficient
Instead of eyeballing trees, you can compare linkage methods with a single number. The agnes() function (in the cluster package) does agglomerative clustering and reports the agglomerative coefficient (AC) — a measure of the strength of the clustering structure, between 0 and 1. Values closer to 1 mean a stronger, clearer structure.agnes() also does the scale() + dist() + linkage in one call.
library(cluster)# Try four linkage methods and grab each agglomerative coefficientmethods <-c(average ="average", single ="single",complete ="complete", ward ="ward")ac <-sapply(methods, function(m) {agnes(USArrests, stand =TRUE, metric ="euclidean", method = m)$ac})round(ac, 3)
average single complete ward
0.738 0.634 0.854 0.934
Ward’s method gives the highest agglomerative coefficient — the strongest clustering structure — which is why we use it. This is a quick, defensible way to pick a linkage method rather than guessing.
Step 3 — the dendrogram
The tree is best read as a dendrogram. The base plot(res.hc) works, but fviz_dend() (in factoextra) draws a far cleaner, publication-ready one.
How to read it. Each leaf at the bottom is one state. Moving up, similar states join into branches, and branches fuse into bigger branches. The height at which two items join (the vertical axis) is their dissimilarity — the cophenetic distance. The lower two items fuse, the more similar they are.
Warning
Judge similarity by fusion height, not horizontal position. Two leaves that happen to sit next to each other along the bottom may only join at a high level — they are not necessarily similar. Only the height where their branches first merge tells you how close they are.
Step 4 — cut the tree into groups
A dendrogram by itself doesn’t tell you how many clusters there are. You decide, by cutting the tree at a height — every branch the cut crosses becomes a cluster. cutree() does this, either by a target number of groups (k =) or a cut height (h =). It returns the cluster number of each observation.
df <-scale(USArrests)res.hc <-hclust(dist(df), method ="ward.D2")# Cut the tree into 4 groupsgrp <-cutree(res.hc, k =4)# Cluster label of the first 4 stateshead(grp, 4)
Alabama Alaska Arizona Arkansas
1 2 2 3
# How many states in each cluster?table(grp)
grp
1 2 3 4
7 12 19 12
# Which states are in cluster 1?rownames(df)[grp ==1]
Draw the cut on the dendrogram — fviz_dend() colours the branches by group and boxes each cluster:
library(factoextra)df <-scale(USArrests)res.hc <-hclust(dist(df), method ="ward.D2")fviz_dend(res.hc, k =4, # cut into 4 groupscex =0.5, # label sizek_colors =c("#3a86d4", "#00AFBB", "#E7B800", "#FC4E07"),color_labels_by_k =TRUE, # colour labels by grouprect =TRUE) # box each cluster
You can also see the clusters as a scatter plot. fviz_cluster() projects the states onto their first two principal components and draws a frame around each group — a clearer view of separation than the tree:
library(factoextra)df <-scale(USArrests)res.hc <-hclust(dist(df), method ="ward.D2")grp <-cutree(res.hc, k =4)fviz_cluster(list(data = df, cluster = grp),palette =c("#3a86d4", "#00AFBB", "#E7B800", "#FC4E07"),ellipse.type ="convex", # frame around each clusterrepel =TRUE, # avoid label overlapshow.clust.cent =FALSE,ggtheme =theme_minimal())
Verify the cluster tree: the cophenetic correlation
How faithfully does the tree reflect the original distances? Compute the cophenetic distances — the heights at which pairs merge in the tree — and correlate them with the original dist() distances. The closer to 1, the better the tree preserves the real distances; above 0.75 is considered good.
df <-scale(USArrests)res.dist <-dist(df)res.hc <-hclust(res.dist, method ="ward.D2")# Cophenetic distances from the treeres.coph <-cophenetic(res.hc)# Correlation with the original distancescor(res.dist, res.coph)
[1] 0.6975266
Ward’s tree preserves the distances reasonably. Average linkage often scores higher on this particular statistic (one reason it’s popular) — compare:
Average linkage gives a higher cophenetic correlation here — it represents the raw distances slightly more faithfully. That doesn’t make it the “best” choice outright: it trades off against the compact, balanced groups Ward gives (and Ward’s higher agglomerative coefficient). Pick the linkage that matches your goal, not just one number — see the decision cue below.
Divisive clustering (DIANA)
Divisive clustering — DIANA (DIvisive ANAlysis) — is agglomerative clustering run in reverse. It starts with all observations in one cluster and, at each step, splits off the most heterogeneous cluster, until every observation is on its own. Where agglomerative is bottom-up, divisive is top-down; where agglomerative is good at finding small clusters, divisive is good at finding large ones.
The diana() function (in cluster) computes it and, like agnes(), does scale() + dist() + the algorithm in one call. It returns a divisive coefficient (analogous to the agglomerative coefficient) measuring the strength of the structure.
library(cluster)library(factoextra)# Divisive clustering (standardizes internally)res.diana <-diana(USArrests, stand =TRUE)# Divisive coefficient: strength of the clustering structureres.diana$dc
[1] 0.8530481
# Visualize the tree, cut into 4 groupsfviz_dend(res.diana, cex =0.5,k =4,palette ="jco")
You read, cut and verify a DIANA tree exactly like an agglomerative one (cutree(), fviz_dend(), cophenetic()). In practice agglomerative clustering is used far more often, but DIANA is a useful alternative when you expect a few large groups rather than many small ones.
Which linkage when
You want…
Use
Compact, balanced, roughly equal-sized groups (a safe default)
Ward (ward.D2)
Tight, compact clusters; sensitive to the farthest points
Complete
A middle-ground; best cophenetic correlation
Average
To detect outliers / chaining (rarely for grouping)
Single
A few large groups, top-down
Divisive (diana())
Confirm your choice with the agglomerative coefficient (agnes()$ac) and the cophenetic correlation (cor(dist, cophenetic(hc))) — don’t pick by eye alone.
Try it live
Cluster the USArrests states yourself. Change k to cut the tree into a different number of groups, or swap "ward.D2" for "complete" or "average" and watch the dendrogram change. Click Run.
🟢 With an AI agent
Ask Prova“run a hierarchical clustering on my data and tell me how many clusters to keep” — it answers with R code you can run on your own data frame, then helps you read the dendrogram, choose the cut, and check the cophenetic correlation. The runtime is the judge.Ask Prova →
Common issues
ward.D vs ward.D2 — which one? Use ward.D2. The original "ward.D" does not implement Ward’s criterion correctly unless your input is squared Euclidean distances; "ward.D2" squares the distances internally and gives the genuine Ward result. Reach for ward.D2 unless you have a specific reason not to.
I forgot to scale and one variable dominates. If your variables are on different scales (e.g. dollars vs. counts), the largest-magnitude variable will drive the distances and the clusters will essentially reflect that one column. Standardize first with scale() (or agnes(..., stand = TRUE)).
How do I know where to cut the tree? There’s no single rule, but look for a large vertical gap — cut just below a height where branches jump up a long way (big jumps mean very different clusters are being forced together). For a principled choice, use the optimal number of clusters methods (elbow, silhouette, gap statistic) and pass that k to cutree().
My single-linkage tree looks like one long chain. That’s single linkage’s known “chaining” behaviour — it links clusters by their single closest pair. Switch to complete or Ward for compact groups.
Frequently asked questions
NoteWhat is the difference between hierarchical and k-means clustering?
k-means requires you to pick the number of clusters (k) up front and returns a flat partition into exactly that many groups; it scales to large data. Hierarchical clustering builds a whole tree (dendrogram) of nested clusters and lets you choose the number afterwards by cutting the tree — but the distance matrix makes it impractical for very large datasets. Use hierarchical clustering to explore structure and k-means to scale.
NoteWhich linkage method should I use for hierarchical clustering?
Ward’s method (ward.D2) and complete linkage are the usual defaults — they give compact, balanced clusters. Average linkage is a middle ground that often maximizes the cophenetic correlation. Single linkage chains and is mostly useful for spotting outliers. Compare them objectively with the agglomerative coefficient from agnes() (closer to 1 = stronger structure).
NoteHow do I cut a dendrogram into clusters in R?
Use cutree() on the hclust() output: cutree(res.hc, k = 4) cuts into 4 groups, or cutree(res.hc, h = 5) cuts at height 5. It returns the cluster number of each observation. To draw the cut, pass k = and rect = TRUE to fviz_dend().
NoteWhat is the difference between agglomerative and divisive clustering?
Agglomerative (AGNES) is bottom-up: each observation starts alone and the closest clusters merge step by step. Divisive (DIANA) is top-down: everything starts in one cluster that is split repeatedly. Agglomerative is better at finding small clusters and is by far the more common; divisive is better at finding a few large clusters.
NoteHow do I check whether my dendrogram is any good?
Compute the cophenetic correlation: cor(res.dist, cophenetic(res.hc)). It compares the merge heights in the tree to the original pairwise distances — closer to 1 is better, and above 0.75 is considered good. The average linkage method often scores highest on this measure.
Test your understanding
ImportantExercise: cluster with complete linkage
Build a hierarchical clustering of the standardized USArrests data with complete linkage, cut it into 3 groups, and print how many states fall in each.
# method = "complete" inside hclust(), and k = 3 inside cutree()
df <-scale(USArrests)res.hc <-hclust(dist(df), method ="complete")grp <-cutree(res.hc, k =3)table(grp)
Conceptual. In a dendrogram, two states sit right next to each other along the bottom axis but their branches only join near the very top. Are they similar? (Answer: No — similarity is read from the height at which branches fuse, not from horizontal position. A high fusion height means they are dissimilar.)
Conceptual. You compare four linkage methods with agnes() and Ward has the highest agglomerative coefficient while average has the highest cophenetic correlation. Which do you pick? (Answer: There’s no single “right” one — Ward gives the strongest, most compact structure; average reproduces the raw distances most faithfully. Choose by your goal, and confirm the cut with the optimal number of clusters methods.)
Conclusion
Hierarchical clustering gives you a tree of nested groups instead of a fixed partition: compute a distance matrix with dist(), link it into a tree with hclust() (or agnes()), pick a linkage method — ward.D2 is a strong default, confirmed by the agglomerative coefficient — draw it with fviz_dend(), and cut it into groups with cutree(). Check the fit with the cophenetic correlation, and reach for divisive clustering (diana()) when you expect a few large groups. The number of clusters is a decision you make from the tree, ideally backed by the formal methods in the next lessons.
Related lessons
Build on this:distance measures — the similarity rule every linkage method depends on, and how to choose it; k-means — the partitioning alternative when you do know k and need to scale; optimal number of clusters — elbow, silhouette and gap statistic to choose where to cut; visualizing dendrograms — zoom, subtrees and prettier trees with dendextend; comparing dendrograms — tanglegrams and correlation between two trees.