2
votes

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

1
Please provide minimum reproducible data we can run your code on, e.g. paste the output of dput(ibs_mat) or a subsetDjork
@R.S. An example file created by dput(ibs_mat) was added in the question.IsoBar
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
@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

1 Answers

2
votes

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