Я сгенерировал эту дендрограмму , используя функции R * hclust()
, as.dendrogram()
и plot.dendrogram()
.
Я использовал функцию dendrapply()
и локальную функцию для окраски листьев, которая работает нормально.
У меня есть результаты статистического теста, которые показывают, являются ли набор узлов ( например, кластер "_+v\_stat5a\_01_
" и "_+v\_stat5b\_01_
" в правом нижнем углу дерева) значительный или важный.
У меня также есть локальная функция, которую я могу использовать с dendrapply()
, которая находит точный узел в моей дендрограмме, который содержит значительные листы.
Я бы хотел (следуя примеру):
- Раскрасить края, которые соединяют "
_+v\_stat5a\_01_
" и "_+v\_stat5b\_01_
"; или
- Нарисуйте
rect()
вокруг "_+v\_stat5a\_01_
" и "_+v\_stat5b\_01_
"
У меня есть следующая локальная функция (детали условия «node-in-leafList-match-node-in-clusterList» не важны, но они выделяют важные узлы):
markSignificantClusters <<- function (n) {
if (!is.leaf(n)) {
a <- attributes(n)
leafList <- unlist(dendrapply(n, listLabels))
for (clusterIndex in 1:length(significantClustersList[[1]])) {
clusterList <- unlist(significantClustersList[[1]][clusterIndex])
if (nodes-in-leafList-match-nodes-in-clusterList) {
# I now have a node "n" that contains significant leaves, and
# I'd like to use a dendrapply() call to another local function
# which colors the edges that run down to the leaves; or, draw
# a rect() around the leaves
}
}
}
}
Из этого блока if
я пытался вызвать dendrapply(n, markEdges)
, но это не сработало:
markEdges <<- function (n) {
a <- attributes(n)
attr(n, "edgePar") <- c(a$edgePar, list(lty=3, col="red"))
}
В моем идеальном примере ребра, соединяющие "_+v\_stat5a\_01_
" и "_+v\_stat5b\_01_
", были бы пунктирными и красного цвета.
Я также пытался использовать rect.hclust()
в этом if
блоке:
ma <- match(leafList, orderedLabels)
rect.hclust(scoreClusterObj, h = a$height, x = c(min(ma), max(ma)), border = 2)
Но результат не работает с горизонтальными дендрограммами (, т.е. дендрограммы с горизонтальными метками). Вот пример (обратите внимание на красную полосу в правом нижнем углу). Что-то не так с размерами того, что генерирует rect.hclust()
, и я не знаю, как это работает, чтобы написать свою собственную версию.
Я ценю любой совет, чтобы заставить edgePar
или rect.hclust()
работать должным образом, или чтобы я мог написать свой собственный rect.hclust()
эквивалент.
UPDATE
С тех пор как я задал этот вопрос, я использовал getAnywhere(rect.hclust())
, чтобы получить функциональный код, который вычисляет параметры и рисует объект rect
. Я написал собственную версию этой функции для обработки горизонтальных и вертикальных листьев и назвал ее с помощью dendrapply()
.
Однако существует некоторый эффект отсечения, который удаляет часть rect
. Для горизонтальных листьев (листьев, которые нарисованы на правой стороне дерева), правый край rect
либо исчезает, либо тоньше ширины границы трех других сторон rect
. Для вертикальных листьев (листьев, которые нарисованы в нижней части дерева), самый нижний край rect
страдает той же проблемой отображения.
То, что я сделал для обозначения значительных кластеров, - это уменьшение ширины rect
так, чтобы я рисовал вертикальную красную полосу между концами краев кластера и (горизонтальными) листовыми метками.
Это устраняет проблему отсечения, но вводит другую проблему в том, что пространство между концами краев кластера и метками листьев имеет ширину всего около шести пикселей, и я не контролирую это. Это ограничивает ширину вертикальной полосы.
Хуже всего то, что x
-координата, которая отмечает, где вертикальная полоса может поместиться между двумя элементами, будет меняться в зависимости от ширины большего дерева (par["usr"]
), что, в свою очередь, зависит от того, как дерево иерархия оказывается структурированной.
Я написал «исправление» или, лучше сказать, хак, чтобы скорректировать это значение x
и ширину rect
для горизонтальных деревьев. Это не всегда работает согласованно, но для деревьев, которые я создаю, кажется, не дают слишком близко (или накладываются) края и метки.
В конечном счете, лучшим решением было бы выяснить, как нарисовать rect
, чтобы не было отсечения. Или последовательный способ вычисления конкретной позиции x
между краями дерева и метками для любого данного дерева, чтобы правильно расположить по центру и размеру полосы.
Меня также очень заинтересовал бы метод аннотирования кромок цветами или стилями линий.