Заставьте dendextend назначать цвета для ветвей, где я предварительно установил цвета для листьев - PullRequest
0 голосов
/ 30 октября 2018

Я хочу установить цвет ветвей моей дендрограммы, учитывая назначенные вручную группы моих листьев. Так что я заранее знаю, что хочу покрасить, например. листья A-C красного цвета, а все ветви, которые ведут только к красным листьям, также должны быть красного цвета.

Я могу раскрасить ветви моей дендрограммы, используя пакет "dendextend". Тем не менее, я не контролирую, какой цвет будет назначен какому идентификатору кластера. dendrextend назначает первый цвет первому идентификатору кластера, который он находит, независимо от того, является ли он идентификатором 1. Однако мне нужен идентификатор 1, окрашенный в цвет 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)}

Результат:

Листья окрашены не в желаемом порядке, а по кластерной позиции на графике слева направо

Dendrogram with wrong coloring

Если вы измените строку set.seed(...) на set.seed(12345), вы увидите, что окраска кажется правильной. Но это потому, что кластеры появляются в правильном порядке случайно, если смотреть слева направо:

Dendrogram with correct coloring

Как заставить color_branches() назначать цвета по идентификатору кластера, а не по тому, какой кластер стоит первым?

Другие ТАК вопросы, которые я пытался

1 Ответ

0 голосов
/ 01 ноября 2018

Обходной путь должен использовать функцию 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). Сравните с изображением выше:

dendrogram with correct coloring

...