给我手动分配的叶子组,我想设置树状图的分支颜色。所以我事先知道我想上色将A-C叶片染成红色,并且所有仅导致红色叶片的分支也应染成红色。
我可以使用“ dendextend”包为树状图的分支着色。
但是,我无法控制将哪种颜色分配给哪个群集ID。 dendrextend
会将第一种颜色分配给找到的第一个群集ID,而不管它是否是ID1。但是,我需要用颜色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而不是首先出现的群集分配颜色?
Dendextend: Regarding how to color a dendrogram’s labels according to defined groups:此问题是相关的,但仅针对着色标签。
Color dendrogram branches based on external labels uptowards the root until the label matches。提出了一个答案branches_attr_by_cluster
,我将其翻译成示例:
den <- den %>%
branches_attr_by_clusters(
values = clucols[dat$gi[o]],
clusters = dat$gi[o],
attr = "col")
但是,结果还是一样
答案 0 :(得分:0)
一种解决方法是使用函数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::reduce
或base::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)
的结果。与上图比较: