【问题标题】:Make dendextend assign colors to branches where I preset colors for leaves让dendextend为我为叶子预设颜色的分支分配颜色
【发布时间】:2018-10-30 17:48:33
【问题描述】:

给定手动分配的叶子组,我想设置树状图分支的颜色。所以我提前知道我想着色,例如叶子A-C是红色的,所有只长出红色叶子的树枝也应该染成红色。

我可以使用“dendextend”包为我的树状图的分​​支着色。 但是,我无法控制将哪种颜色分配给哪个集群 ID。 dendrextend 将第一个颜色分配给它找到的第一个集群 ID,无论它是否是 ID 1。但是,我需要以颜色 1 等颜色着色的 ID 1,因为我需要一个图例。

请参阅此示例。我想要一个树状图,它将标签和分支A-C 涂成红色,D-F 涂成蓝色,G-I 涂成绿色。

suppressPackageStartupMessages(library(dendextend))
library(dplyr)

set.seed(12346)
# Sample data: 
# ------------
# l = Leaf labels | g = assigned color of leaf | x = value for clustering
dat <- tibble(l = LETTERS[1:9],
              g = factor(rep(letters[1:3], each = 3)),
              x = round(runif(9,0,10)))

# color_branches() need integer cluster IDs
dat$gi <- dat$g %>% as.integer()

# Color IDs of each group
dat %>% distinct(g, gi)
## # A tibble: 3 x 2
##   g        gi
##   <fct> <int>
## 1 a         1
## 2 b         2
## 3 c         3
# ID 1 = red, ID 2 = blue, ID 3 = green
clucols <- c("red", "blue", "green")

# Clustering & Dendrogram
# -----------------------
dst <- dist(setNames(dat$x, dat$l))
den <- as.dendrogram(hclust(dst))
o <- order.dendrogram(den)

den <- den %>%
  color_branches(col = clucols, clusters = dat$gi[o]) 
# Transfer branch colors to labels
labels_colors(den) <- get_leaves_branches_col(den)

plot(den)

# Legend
dat %>% distinct(g, gi) %>%
{legend("topright", legend = .$g, col = clucols[.$gi], lty = 1)}

结果:

叶子不是按我想要的顺序着色,而是按图上从左到右的簇位置排列

如果您将set.seed(...) 行更改为set.seed(12345),您会看到颜色看起来是正确的。但这是因为如果从左到右看,这些簇会偶然以正确的顺序出现:

我如何让color_branches() 按集群 ID 分配颜色,而不是按哪个集群先分配颜色?

我尝试过的其他 SO 问题

【问题讨论】:

    标签: r plot dendrogram dendextend


    【解决方案1】:

    一种解决方法是使用函数branches_attr_by_labels 将颜色分别分配给每个组的分支。

    在问题中替换此代码:

    den <- den %>%
      color_branches(col = clucols, clusters = dat$gi[o]) 
    

    使用下面的代码。

    您需要获取一个列表,其中包含每个组的每个元素。每个元素依次包含您要着色的标签和颜色本身。例如,您可以像这样得到它:

    library(purrr)
    colmap <- dat %>% group_by(g) %>% summarise(l = list(l)) %>% transpose()
    colmap
    
    ## [[1]]
    ## [[1]]$g
    ## [1] 1
    ## 
    ## [[1]]$l
    ## [1] "A" "B" "C"
    ## 
    ## 
    ## [[2]]
    ## [[2]]$g
    ## [1] 2
    ## 
    ## [[2]]$l
    ## [1] "D" "E" "F"
    ## 
    ## 
    ## [[3]]
    ## [[3]]$g
    ## [1] 3
    ## 
    ## [[3]]$l
    ## [1] "G" "H" "I"
    

    然后,对于每个元素,应用branches_attr_by_labels。因为它需要一个树状图和 一些更改参数并返回树状图,您可以使用purrr::reducebase::Reduce

    den <- reduce(.x = colmap, .init = den, .f = function(d, m) 
      branches_attr_by_labels(d, m$l, clucols[m$g] ))
    

    或者,稍微长一点:

    for(e in colmap){
      den <- branches_attr_by_labels(den, e$l, clucols[e$g])
    }
    

    set.seed(123456) 的结果。对比上图:

    【讨论】:

      猜你喜欢
      • 2015-12-02
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 2016-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多