如何在R树形图中正确着色边缘或绘制rects?

Ale*_*lds 8 r dendrogram edge-detection hclust

我产生这种树状图,使用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
       }
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

在这个if区块内,我尝试过调用dendrapply(n, markEdges),但这不起作用:

markEdges <<- function (n) {
  a <- attributes(n)
  attr(n, "edgePar") <- c(a$edgePar, list(lty=3, col="red"))
}
Run Code Online (Sandbox Code Playgroud)

在我的理想示例中,连接" _+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)
Run Code Online (Sandbox Code Playgroud)

但结果不适用于水平树形图(带水平标签的树状图).这是一个例子(注意右下角的红色条纹).关于rect.hclust()生成的维度的某些方面是不正确的,我不知道它是如何工作的,能够编写我自己的版本.

我很欣赏任何关于获得edgeParrect.hclust()正常工作的建议,或者能够写出我自己的rect.hclust()等价物.

UPDATE

自从提出这个问题以来,我曾经getAnywhere(rect.hclust())得到了计算参数和绘制rect对象的功能代码.我写了一个这个函数的自定义版本来处理水平和垂直叶子,并调用它dendrapply().

但是,有一种削减效果可以消除部分内容rect.对于水平叶子(在树的右侧绘制的叶子),它们的最右边rect消失或者比其他三边的边缘宽度更薄rect.对于垂直叶子(在树的底部绘制的叶子),最底部的边缘rect会遇到相同的显示问题.

我作为标记重要簇的方法所做的是减小这样的宽度,rect使得在簇边缘的尖端和(水平)叶片标签之间呈现垂直红色条纹.

这消除了剪切问题,但引入了另一个问题,因为簇边缘尖端和叶子标签之间的空间只有六个左右像素宽,我没有太多的控制权.这限制了垂直条纹的宽度.

更糟糕的问题是,x标记垂直条纹在两个元素之间可以适合的位置的坐标将根据较大树(par["usr"])的宽度而改变,而树的宽度又取决于树层次结构的结构.

我写了一个"修正",或者更好地称为修正这个x值和rect水平树木宽度的黑客.它并不总是一致地工作,但对于我正在制作的树木,它似乎不会太靠近(或重叠)边缘和标签.

最终,一个更好的解决方法是找出如何绘制,rect以便没有裁剪.或者一致的方法来计算x树边缘和任何给定树的标签之间的特定位置,以便正确地居中和调整条纹的大小.

我也对使用颜色或线条样式注释边缘的方法非常感兴趣.

Mar*_*usQ 2

所以您实际上问了大约五个问题 (5 +/- 3)。至于编写您自己的 rect.hclust 之类的函数,library/stats/R/identify.hclust.R如果您想查看源代码,就可以查看它。

我自己快速浏览了一下它,不确定它是否按照我在阅读您的描述时所认为的那样做了——它似乎正在绘制多个矩形,此外,x选择器似乎是硬编码的以水平分隔标签(这不是不是你想要的,也没有y)。

我会回来的,但与此同时,您可能(除了查看源代码之外)尝试使用不同的border=颜色和不同的h=值执行多个 rect.hclust 以查看是否出现故障模式。

更新

我在这方面也没有太多运气。

剪切的一种可能的混乱是用尾随空格填充标签,然后稍微将矩形的边缘带入(其想法是,仅将矩形带入即可将其移出剪切区域,但会覆盖标签的末端)。

另一个想法是用半透明(低 Alpha)颜色填充矩形,形成阴影区域而不是边界框。