2

I'm currently constructing a dendrogram and I'm using 'dendextend' to tweak the look of it. I've been able to do everything I want to (labelling leaves and highlighting branches of my chosen clusters), except drawing rectangles around pre-defined clusters.

My data (which can be sourced from this file: Barra_IBS_example.matrix) was clustered with 'pvclust', so 'pvrect' draws the rects in the correct position, but it cuts the labels (see image below), so I want to reproduce it with 'rect.dendrogram', however, I can't figure out how to tell the function to use the clustering data from 'pvclust'.

dendrogram with pvrect

This is the code I'm using:

idnames <- dimnames(ibs_mat)[[1]]
ibs.pv <- pvclust(ibs_mat, nboot=1000)
ibs.clust <- pvpick(ibs.pv, alpha=0.95)
names(ibs.clust$clusters) <- paste0("Cluster", 1:length(ibs.clust$clusters))
# Choose a colour palette
pal <- brewer.pal(length(ibs.clust$clusters), "Paired")
# Transform the list to a dataframe
ibs_meta <- bind_rows(lapply(names(ibs.clust$clusters), 
       function(l) data.frame(Cluster=l, Sample = ibs.clust$clusters[[l]])))
# Add the rest of the non-clustered samples (and assign them as Cluster0), add colour to each cluster
ibs_table <- ibs_meta %>% 
  rbind(., data.frame(Cluster = "Cluster0", 
                       Sample = idnames[!idnames %in% .$Sample])) %>%
  mutate(Cluster_int=as.numeric(sub("Cluster", "", Cluster))) %>% 
  mutate(Cluster_col=ifelse(Cluster_int==0, "#000000", 
              pal[Cluster_int])) %>% 
  .[match(ibs.pv$hclust$labels[ibs.pv$hclust$order], .$Sample),]
hcd <- as.dendrogram(ibs.pv) %>%  
  #pvclust_show_signif(ibs.pv, show_type = "lwd", signif_value = c(2, 1),alpha=0.25) %>% 
  set("leaves_pch", ifelse(ibs_table$Cluster_int>0,19,18)) %>%  # node point type
  set("leaves_cex", 1) %>%  # node point size
  set("leaves_col", ibs_table$Cluster_col) %>% #node point color
  branches_attr_by_labels(ibs_meta$Sample, TF_values = c(2, Inf), attr = c("lwd")) %>% # change branch width
  # rect.dendrogram(k=12, cluster = ibs_table$Cluster_int, border = 8, lty = 5, lwd = 1.5,
  #                 lower_rect = 0) %>%  # add rectangles around clusters
  plot(main="Barramundi samples IBS based clustering")
pvrect(ibs.pv, alpha=0.95, lwd=1.5)

Many thanks, Ido

IsoBar
  • 405
  • 3
  • 10
  • Please provide minimum reproducible data we can run your code on, e.g. paste the output of `dput(ibs_mat)` or a subset – Djork May 29 '17 at 00:45
  • @R.S. An example file created by `dput(ibs_mat)` was added in the question. – IsoBar May 29 '17 at 03:08
  • 1
    Where does the `idnames` function come from, please clear your workspace and rerun your code to make sure everything is included in the above code, include all libraries that need to be installed. – Djork May 29 '17 at 04:44
  • @R.S. the names are simply the matrix names (though in the example they did derived from an external function). I've updated the code above to use the `dimnames` of the matrix. – IsoBar May 29 '17 at 12:32

1 Answers1

2

ok, this took more work than I had hoped, but I got a solution for you.

I created a new function called pvrect2 and just pushed it to the latest version of dendextend on github. Here is a self contained example demonstrating the solution:

devtools::install_github('talgalili/dendextend')

library(pvclust)
library(dendextend)
data(lung) # 916 genes for 73 subjects
set.seed(13134)
result <- pvclust(lung[, 1:20], method.dist="cor", method.hclust="average", nboot=10)

par(mar = c(9,2.5,2,0))
dend <- as.dendrogram(result)
dend %>%    
   pvclust_show_signif(result, signif_value = c(3,.5)) %>%
   pvclust_show_signif(result, signif_value = c("black", "grey"), show_type = "col") %>% 
   plot(main = "Cluster dendrogram with AU/BP values (%)")
# pvrect(result, alpha=0.95)
pvrect2(result, alpha=0.95)
text(result, alpha=0.95)

[1]: https://i.stack.imgur.com/GUvdV.png

Tal Galili
  • 24,605
  • 44
  • 129
  • 187
  • 1
    That's great , many thanks for providing a stable solution and not just a one-time workaround!! Highly appreciated. – IsoBar May 30 '17 at 01:56
  • My pleasure :) I think it should be generalized to use rect.dendrogram, but I would get to it at another time... – Tal Galili May 30 '17 at 06:58
  • @TalGalili Is it possible to maintain the AU/BP values annotated above the branches from pvclust? – Djork May 30 '17 at 11:09
  • 1
    Hi @R.S. you just need to add `text(result, alpha=0.95)`. I've updated the answer accordingly. – Tal Galili May 30 '17 at 16:21
  • Hi @TalGalili, I just came back to your solution (for another dataset this time), but when I tried to control the AU/BP text labels attributes (size, color, rotation), only `print.num=FALSE` had an effect on the output. My command was: `text(result, print.num=FALSE, srt=90, cex.pv=0.6, col.pv=c(2,0,0))` – IsoBar Nov 27 '17 at 06:03
  • Hi @IsoBar this is a limitation of pvclust, not of dendextend. The text function is from pvclust. Run ?text.pvclust to see the options you can control. They are: text(x, col=c(2,3,8), print.num=TRUE, float=0.01, cex=NULL, font=NULL, ...) So you could re-write your commend to get partial effect. text(result, col=c(2,0,0), print.num=TRUE, cex=0.6) (notice this is for the labels on the nodes, not the bottom labels) – Tal Galili Nov 28 '17 at 08:37
  • If you want to control the bottom labels, have a look at this tutorial: https://cran.r-project.org/web/packages/dendextend/vignettes/introduction.html#setting-a-dendrograms-labels – Tal Galili Nov 28 '17 at 08:38