talgalili / dendextend

Extending R's Dendrogram Functionality
152 stars 28 forks source link

get_subdendrograms doesn't work recursively? #85

Closed rec3141 closed 5 years ago

rec3141 commented 5 years ago

Any idea why this doesn't work? It outputs two leaves instead of two subdendrograms. Thanks.

hm <- heatmap(as.matrix(iris[,-5]),keep.dendro=T)
get_subdendrograms(get_subdendrograms(hm$Rowv,2)[[2]],2)

PS what I'm actually trying to do is break up the dendrogram into sub-dendrograms each with a maximum number of leaves, for plotting huge heatmaps.

rec3141 commented 5 years ago

I think this is because sub_dendrograms() calls find_dendrogram() which uses unlist() to get numeric ids, when I changed it to use the node labels it worked. Here's the whole thing:

find_dendrogram() clone

find_trees <- function (dend, selected_labels)
{

    if (all(get_leaves_attr(dend,"label") %in% selected_labels)) {
        return(dend)
    }
    if (any(get_leaves_attr(dend[[1]],"label") %in% selected_labels)) {
        return(find_trees(dend[[1]], selected_labels))
    }
    else {
        return(find_trees(dend[[2]], selected_labels))
    }
}

get_dendrograms() clone

get_subtrees <- function (dend, k)
{
    clusters <- cutree(dend, k)
    dend_list <- lapply(unique(clusters), function(cluster.id) {
        find_trees(dend, names(which(clusters == cluster.id)))
    })
    class(dend_list) <- "dendlist"
    dend_list
}

new function to break a dendrogram into sub-dendrograms with a given maximum size, returns a list of labels.

splitree <- function(dend,max.size=96) {
    saved <- list()
    ct <- get_subtrees(dend,2)
    for(subtree in ct) {
        lab <- get_leaves_attr(subtree,"label")
        if(length(lab) > max.size) {
            saved[[length(saved)+1]] <- splitree(subtree,max.size)
        } else {
            print(length(lab))
            saved[[length(saved)+1]] <- lab
        }
    }

    flatten <- function(x) {
      if (!inherits(x, "list")) return(list(x))
      else return(unlist(c(lapply(x, flatten)), recursive = FALSE))
    }

    flatten(saved)
}
talgalili commented 5 years ago

tl;dr: should there be any change to the code in the package?