Ответ 1
Хорошо, вот очень хакерское решение. Я убежден, что есть лучшие, но это первый удар, так что несите меня.
Идея состоит в том, чтобы искать объект dend
(который является внутренним списком) для соответствующих имен элементов (в данном случае только числа) и извлекать соответствующий цвет, сохранять его в кадре данных и использовать его для легенда.
# First we'll extract the elements and corresponding categories...
categories <- cutree(dend, k = 5)
# ... and save them in a data frame
categories_df <- data.frame(elements = as.numeric(names(categories)),
categories = categories,
color = NA)
# now here a little function that extracts the color for each element
# from the 'dend' object. It uses the list.search() function from the
# 'rlist' package
library(rlist)
extract_color <- function(element_no, dend_obj) {
dend.search <- list.search(dend_obj, all(. == element_no))
color <- attr(dend.search[[1]], "edgePar")$col
return(color)
}
# I use 'dplyr' to manipulate the data
library(dplyr)
categories_df <- categories_df %>%
group_by(elements) %>%
mutate(color = extract_color(elements, dend))
Теперь это дает нам следующий фрейм данных:
> categories_df
Source: local data frame [40 x 3]
Groups: elements [40]
elements categories color
(dbl) (int) (chr)
1 1 1 #CB410B
2 2 1 #CB410B
3 3 1 #CB410B
4 4 1 #CB410B
5 5 1 #CB410B
6 6 2 #009000
7 7 1 #CB410B
8 8 1 #CB410B
9 9 3 #007FFF
10 10 1 #CB410B
.. ... ... ...
Мы можем суммировать это с кадром данных только с цветами для категорий, например
legend_data <- categories_df %>%
group_by(categories) %>%
summarise(color = unique(color))
> legend_data
Source: local data frame [5 x 2]
categories color
(int) (chr)
1 1 #CB410B
2 2 #009000
3 3 #007FFF
4 4 #FF033E
5 5 #3B444B
Теперь легко сгенерировать легенду:
circlize_dendrogram(dend)
legend(-1.05, 1.05, legend = legend_data$categories, fill = legend_data$color, cex = 0.7)
Что дает вам:
Вы можете использовать cutree(dend, k = 5)
для подтверждения того, что номера цветов категорий соответствуют категории каждого элемента.