Question: heatmap.2 reorder branches
2
3.1 years ago by
Benn7.9k
Netherlands
Benn7.9k wrote:

Hello,

I am using hierarchical clustering with `heatmap.2`, and would like to reorder the tree generated for the columns. I have searched here, on bioconductor, and on google but don't seem to find the right solution. Wondering if someone here knows how to manipulate the tree.

In more detail, I have clustered with the following code, and the column tree is perfect, except that I would like the red group left of the blue one (so between green and blue). I know from evolution biology class that these branches in theory can be turned (like a baby mobile). But I don't know how to do this with `heatmap.2`, I guess I would have to use the `reorderfun`, but don't know how?

``````heatmap.2(z_RPKM_ro, key = TRUE, col=blueyellow, density.info=c("none"),
scale = c("none"), trace=c("none"), cexCol=1, cexRow=0.7, key.xlab="Row Z-score",
hclustfun = function(x) hclust(x, method = "ward.D"), dendrogram="both",
distfun = function(x) dist(x, method = "euclidean"),
labRow = F, RowSideColors = colorset, ColSideColors = colorBar2)
``````

Ben

modified 2.8 years ago by Xianjun270 • written 3.1 years ago by Benn7.9k

You could reorder the matrix and then plot it using heatmap.2

http://stackoverflow.com/questions/27959044/heatmap-2-specify-row-order-or-prevent-reorder

Thanks for your suggestion, but my point is the dendrogram. The dendrogram is showing that the replicates of my groups cluster nice together. Of course I can manually reorder the matrix/heatmap, but will lose then the information of the dendrogram.

Is it possible to rearrange the dendrogram horizontally? Since the distance is depicted vertically, it won't mess up the outcome of the dendrogram.

2
3.0 years ago by
e.rempel800
Germany, Heidelberg, COS
e.rempel800 wrote:

Hi b.nota,

my response is kind of late, but here it is. I assume one possible way is to pass explicitly reordered dendrogram as a parameter to function heatmap.2. Let me show it with the following example:

``````library(gplots)
data(mtcars)
x <- as.matrix(mtcars)
heatmap.2(x, margins = c(5,10))
``````

On my machine, I obtain following graphic

Now just assume I would like to swap some branches to have Ferrari Dino at the bottom and Duster 360 at the top of row dendrogram. In your case, you would like to swap red and blue samples. For this purpose, I first recalculate the actual row dendrogram

``````row.hc <- hclust(dist(x))
row.dd <- as.dendrogram(row.hc)
``````

Now I manually assign weights to specific columns

``````weights.dd <- ifelse(rownames(x) == "Ferrari Dino", yes = 1, no = 50) + ifelse(rownames(x) == "Duster 360", yes = 950, no = 0)
``````

This line ensures that Ferrari Dino gets weight 1 and Duster 360 weight 1000. In your case you could manually assign weight 1 to brown samples, weight 10 to green, 100 to red, and 1000 to blue (I am not sure about this, you have to find it out). Now I use the function reorder to reorder the row dendrogram

``````row.dd.reordered <- reorder(row.dd, wts = weights.dd, agglo.FUN = mean)
``````

and use it for the new call of heatmap.2

``````heatmap.2(x, Rowv = row.dd.reordered, margins = c(5,10))
``````

Then I obtain the following graphic

HTH

Hi e.rempel,

Thank you for your suggestion. Your example does seem to work indeed, do you know how I can find the right values for my tree?

Hi, I had always to find it experimentally ;). I have assigned some weights to samples, reordered dendrogram and plotted it. It it was ok, I passed it to call of heatmap.2. Unfortunately, I dont know the direct way of computing these values.

2
2.8 years ago by
Xianjun270
Great Boston Area
Xianjun270 wrote:

I had the same problem of using the order function with proper weight, and I just figured out the trick.

Taking the `mtcars` dataset in e.rempel's example above, we first run the default `hclust` to get the dendrogram.

``````data(mtcars)
x <- as.matrix(head(mtcars))  # only using the first 6 cars for demo purpose
row.hc <- hclust(dist(x))
row.dd <- as.dendrogram(row.hc)
par(mar=c(8,3,1,1))
plot(row.dd)
``````

``````> labels(row.dd)  # dendrogram leaves
[1] "Hornet Sportabout" "Hornet 4 Drive"    "Valiant"           "Datsun 710"
[5] "Mazda RX4"         "Mazda RX4 Wag"
# Note that this is differt from
> rownames(x)  # original data labels
[1] "Mazda RX4"         "Mazda RX4 Wag"     "Datsun 710"        "Hornet 4 Drive"
> order.dendrogram(row.dd)  # the index of dendrogram leaves in original data
[1] 5 4 6 3 1 2
``````

To mimic the dendrogram leaves via recorder(), we have to call order() to get the order of the index. This is the trick!! e.g.

``````plot(reorder(row.dd, wts = order(order.dendrogram(row.dd))))
``````

This will reproduce the same plot as plot(row.dd) above.

From this, I learned that, if I want to reorder the tree leaves in a new order, e.g. "Hornet Sportabout", "Valiant","Hornet 4 Drive","Mazda RX4", "Mazda RX4 Wag", "Datsun 710". I will first need to get its index in the original data labels using `match()`, then call `order()` to the order of the index, finallly run `reorder()` with the new order. Here is it:

``````neworder = c("Hornet Sportabout", "Valiant","Hornet 4 Drive","Datsun 710","Mazda RX4", "Mazda RX4 Wag")
row.dd.reordered  = reorder(row.dd, wts = order(match(neworder, rownames(x))))
plot(row.dd.reordered)
``````

Great! Thanks for explaining it. I actually wanted to move whole branches (containing more leafs). Like in your example put the mazda group before Datsun.

``````neworder = c("Hornet Sportabout", "Valiant", "Hornet 4 Drive", "Mazda RX4", "Mazda RX4 Wag", "Datsun 710")
row.dd.reordered  = reorder(row.dd, wts = order(match(neworder, rownames(x))))
plot(row.dd.reordered)
``````

But that doesn't seem to work...

Image

Hi b.note,

I assume it doesn't work since reorder (or actually reorder.dendrogram) agglomerate node weights to obtain "weights" of branches/subtrees. Per default, agglomeration function summarizes the weights, thus to put a specific branch before the others, you might need to assign a very high value.

Yeah it doesn't work, with reorder function you can only switch two leafs in the same branch. I wanted to switch whole branches containing more leafs per branch.

I have tried your weights approach, but can't find the right settings to get exactly the same branches but then switched.

Thanks anyway all for your suggestions!

Sorry to hear that. I had always to experiment with the weights to get the order of branches I want. Maybe it is worth trying different agglo.FUN in reorder (e.g. mean or max)?

1
3.0 years ago by
ivivek_ngs4.9k
Seattle,WA, USA
ivivek_ngs4.9k wrote:

If you want to use different forms of dendrogram then pheatmap package is good to try out which has some sets of methods that can cluster the columns or the rows in different dendrogram based approaches. However if you want to cluster base on your groups for the columns that categorize your columns in that case make an annotation dataframe that groups your samples into the categories and use that to arrange the data in pheatmap switching off the classical clustering method. That will make you understand how the data is organised with your own clustering , in this case your unsupervised clustering is not working.