Как правильно раскрасить края или нарисовать прямоугольники в дендрограмме R?

StackOverflow https://stackoverflow.com/questions/717747

Вопрос

я создал эта дендрограмма используя R hclust(), as.dendrogram() и plot.dendrogram() функции.

Я использовал dendrapply() и локальную функцию для раскрашивания листьев, которая работает нормально.

У меня есть результаты статистического теста, которые показывают, является ли набор узлов (например кластер "_+v\_stat5a\_01_" и "_+v\_stat5b\_01_" в правом нижнем углу дерева) являются значимыми или важными.

У меня также есть локальная функция, которую я могу использовать с dendrapply() это находит точный узел в моей дендрограмме, который содержит значительные листья.

Я хотел бы либо (следуя примеру):

  1. Раскрасьте края, которые соединяются»_+v\_stat5a\_01_" и "_+v\_stat5b\_01_";или,
  2. Нарисовать rect() вокруг "_+v\_stat5a\_01_" и "_+v\_stat5b\_01_"

У меня есть следующая локальная функция (детали условия «nodes-in-leafList-match-nodes-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() эквивалент.

ОБНОВЛЯТЬ

С тех пор, как я задал этот вопрос, я использовал getAnywhere(rect.hclust()) чтобы получить функциональный код, который рассчитывает параметры и рисует rect объект.Я написал специальную версию этой функции для обработки горизонтальных и вертикальных листьев и вызываю ее с помощью dendrapply().

Однако существует своего рода эффект обрезки, который удаляет часть rect.Для горизонтальных листьев (листьев, нарисованных на правой стороне дерева) самый правый край rect либо исчезает, либо становится тоньше ширины границы трех других сторон rect.Для вертикальных листьев (листьев, нарисованных внизу дерева) самый нижний край rect страдает та же проблема с отображением.

Чтобы отметить значимые кластеры, я уменьшил ширину rect так, что я визуализирую вертикальную красную полосу между кончиками краев кластера и (горизонтальными) метками листьев.

Это устраняет проблему отсечения, но создает еще одну проблему, заключающуюся в том, что пространство между краями кластера и метками листьев составляет всего шесть или около того пикселей в ширину, и я не имею особого контроля над этим.Это ограничивает ширину вертикальной полосы.

Хуже проблема заключается в том, что x-координата, которая отмечает место, где может разместиться вертикальная полоса между двумя элементами, будет меняться в зависимости от ширины большего дерева (par["usr"]), что, в свою очередь, зависит от того, как в конечном итоге будет структурирована древовидная иерархия.

Я написал «исправление» или, лучше сказать, хак, чтобы это исправить. x ценность и rect ширина для горизонтальных деревьев.Это не всегда работает стабильно, но для деревьев, которые я создаю, кажется, что он не приближается слишком близко к краям и меткам (или перекрывается).

В конечном счете, лучшим решением было бы узнать, как нарисовать rect чтобы не было обрезки.Или последовательный способ расчета конкретных x расположите полосу между краями дерева и метками для любого данного дерева, чтобы центрировать полосу и правильно ее размер.

Мне также был бы очень интересен метод аннотирования краев с помощью цветов или стилей линий.

Это было полезно?

Решение

Итак, вы на самом деле задали около пяти вопросов (5 +/- 3).Что касается написания собственной функции, подобной rect.hclust, исходный код находится в library/stats/R/identify.hclust.R если хочешь посмотреть.

Я сам взглянул на него и не уверен, что он делает то, что я думал, прочитав ваше описание - кажется, он рисует. несколько прямоугольники, а также x селектор, похоже, жестко запрограммирован для разделения тегов по горизонтали (а это не то, что вам нужно, и нет никакой возможности y).

Я вернусь, а пока вы можете (помимо просмотра исходного кода) попробовать выполнить несколько rect.hclust с разными border= цвета и разные h= значения, чтобы увидеть, возникает ли картина сбоя.

Обновлять

Мне тоже не очень повезло с этим.

Одной из возможных уловок для обрезки было бы заполнить метки конечными пробелами, а затем слегка приблизить край прямоугольника (идея состоит в том, что простое внесение прямоугольника выведет его из зоны отсечения, но перезапишет концы меток). ).

Другая идея — заполнить прямоугольник полупрозрачным цветом (с низким уровнем альфа), создав затененную область, а не ограничивающую рамку.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top