R基于可爱树标签从树状图中获取子树

标签 r hclust dendextend

我对一个大型数据集进行了聚类,并发现了 6 个我有兴趣进行更深入分析的聚类。

我找到了使用带有“ward.D”方法的 hclust 的集群,我想知道是否有办法从 hclust/dendrogram 对象中获取“子树”。

例如

library(gplots)
library(dendextend)

data <- iris[,1:4]
distance <- dist(data, method = "euclidean", diag = FALSE, upper = FALSE)
hc <- hclust(distance, method = 'ward.D')
dnd <- as.dendrogram(hc)
plot(dnd) # to decide the number of clusters
clusters <- cutree(dnd, k = 6)

我用过 cutree获取数据集中每一行的标签。

我知道我可以通过以下方式获取每个相应集群(例如集群 1)的数据:
c1_data = data[clusters == 1,]

是否有任何简单的方法可以获取 dendextend::cutree 返回的每个相应标签的子树? ?例如,假设我对获得

我知道我可以访问树状图的分​​支做类似的事情
subtree <- dnd[[1]][[2]

但是我如何才能准确地获得与集群 1 相对应的子树呢?

我试过了
dnd[clusters == 1]

但这当然行不通。那么如何根据cutree返回的标签获取子树呢?

最佳答案

================ 更新的答案

现在可以使用 get_subdendrograms 解决这个问题。来自 dendextend .

# needed packages:
# install.packages(gplots)
# install.packages(viridis)
# install.packages(devtools)
# devtools::install_github('talgalili/dendextend') # dendextend from github

# define dendrogram object to play with:
dend <- iris[,-5] %>% dist %>% hclust %>% as.dendrogram %>%  set("labels_to_character") %>% color_branches(k=5)
dend_list <- get_subdendrograms(dend, 5)

# Plotting the result
par(mfrow = c(2,3))
plot(dend, main = "Original dendrogram")
sapply(dend_list, plot)

enter image description here

这也可以在热图中使用:
# plot a heatmap of only one of the sub dendrograms
par(mfrow = c(1,1))
library(gplots)
sub_dend <- dend_list[[1]] # get the sub dendrogram
# make sure of the size of the dend
nleaves(sub_dend)
length(order.dendrogram(sub_dend))
# get the subset of the data
subset_iris <- as.matrix(iris[order.dendrogram(sub_dend),-5])
# update the dendrogram's internal order so to not cause an error in heatmap.2
order.dendrogram(sub_dend) <- rank(order.dendrogram(sub_dend))
heatmap.2(subset_iris, Rowv = sub_dend, trace = "none", col = viridis::viridis(100))

enter image description here

================ 旧答案

我认为对您有帮助的是这两个功能:

第一个只是遍历所有集群并提取子结构。这个需要:
  • dendrogram我们想要从中获取子树状图的对象
  • 集群标签(例如由 cutree 返回)

  • 返回子树状图列表。
    extractDendrograms <- function(dendr, clusters){
        lapply(unique(clusters), function(clust.id){
            getSubDendrogram(dendr, which(clusters==clust.id))
        })
    }
    

    第二个执行深度优先搜索以确定集群存在于哪个子树中,如果它与完整集群匹配,则返回它。在这里,我们假设一个集群的所有元素都在一个子树中。这个需要:
  • 树状图对象
  • 簇中元素的位置

  • 返回对应于给定元素簇的子树状图。
    getSubDendrogram<-function(dendr, my.clust){
        if(all(unlist(dendr) %in% my.clust))
            return(dendr)
        if(any(unlist(dendr[[1]]) %in% my.clust ))
            return(getSubDendrogram(dendr[[1]], my.clust))
        else 
            return(getSubDendrogram(dendr[[2]], my.clust))
    }
    

    使用这两个函数,我们可以使用您在问题中提供的变量并获得以下输出。 (我认为该行 clusters <- cutree(dnd, k = 6) 应该是 clusters <- cutree(hc, k = 6) )
    my.sub.dendrograms <- extractDendrograms(dnd, clusters)
    

    绘制列表中的所有六个元素给出所有子树状图

    enter image description here

    编辑

    正如评论中所建议的,我添加了一个函数,该函数作为输入采用树状图 dend和子树的数量k ,但它仍然使用之前定义的递归函数 getSubDendrogram :
    prune_cutree_to_dendlist <- function(dend, k, order_clusters_as_data=FALSE) {
        clusters <- cutree(dend, k, order_clusters_as_data)
        lapply(unique(clusters), function(clust.id){    
            getSubDendrogram(dend, which(clusters==clust.id))
        })
    }
    

    5个子结构的测试用例:
    library(dendextend)
    dend <- iris[,-5] %>% dist %>% hclust %>% as.dendrogram %>% set("labels_to_character") %>% color_branches(k=5)
    
    subdend.list <- prune_cutree_to_dendlist(dend, 5)
    
    #plotting
    par(mfrow = c(2,3))
    plot(dend, main = "original dend")
    sapply(prunned_dends, plot)
    

    我使用 rbenchmark 执行了一些基准测试使用 Tal Galili 建议的函数(此处命名为 prune_cutree_to_dendlist2 ),结果对于上述 DFS 方法非常有希望:
    library(rbenchmark)
    benchmark(prune_cutree_to_dendlist(dend, 5), 
              prune_cutree_to_dendlist2(dend, 5), replications=5)
    
                                    test replications elapsed relative user.self
    1  prune_cutree_to_dendlist(dend, 5)            5    0.02        1     0.020
    2 prune_cutree_to_dendlist2(dend, 5)            5   60.82     3041    60.643
    

    enter image description here

    关于R基于可爱树标签从树状图中获取子树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48167369/

    相关文章:

    r - 如何更改集群中每个组的树状图颜色

    r - Dendextend:关于如何根据定义的组为树状图的标签着色

    r - 如何在绘图上以相同的顺序关联聚类标签和树状图

    r - 如何在R中将'hclust'用作函数调用

    r - sf sfc 对象的坐标转换似乎不起作用

    通过输入 "ALL"返回函数中的所有值

    r - R中水平树状图的树切割和簇周围的矩形

    r - 从 matlab 在 R 中绘制数据

    r - 如何匹配和替换两个数据帧之间的元素