Frage

Ich habe generiert dieses Dendrogramm unter Verwendung von Rs hclust(), as.dendrogram() Und plot.dendrogram() Funktionen.

Ich habe das verwendet dendrapply() Funktion und eine lokale Funktion zum Färben von Blättern, was gut funktioniert.

Ich habe Ergebnisse eines statistischen Tests, die darauf hinweisen, ob eine Reihe von Knoten (z.B. die Ansammlung von „_+v\_stat5a\_01_" Und "_+v\_stat5b\_01_" in der unteren rechten Ecke des Baums) sind bedeutsam oder wichtig.

Ich habe auch eine lokale Funktion, die ich verwenden kann dendrapply() Das findet den genauen Knoten in meinem Dendrogramm, der bedeutende Blätter enthält.

Ich möchte entweder (nach dem Beispiel):

  1. Färben Sie die Kanten, die verbunden sind._+v\_stat5a\_01_" Und "_+v\_stat5b\_01_";oder,
  2. Zeichne ein rect() um "_+v\_stat5a\_01_" Und "_+v\_stat5b\_01_"

Ich habe die folgende lokale Funktion (die Details der Bedingung „Nodes-in-leafList-match-nodes-in-clusterList“ sind nicht wichtig, aber sie hebt wichtige Knoten hervor):

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
       }
     }
  }
}

Von innen heraus if Block, ich habe versucht anzurufen dendrapply(n, markEdges), aber das hat nicht funktioniert:

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

In meinem idealen Beispiel verbinden die Kanten „_+v\_stat5a\_01_" Und "_+v\_stat5b\_01_" wäre gestrichelt und von roter Farbe.

Ich habe es auch mit versucht rect.hclust() Mit diesem if Block:

ma <- match(leafList, orderedLabels)  
rect.hclust(scoreClusterObj, h = a$height, x = c(min(ma), max(ma)), border = 2)

Das Ergebnis funktioniert jedoch nicht mit horizontalen Dendrogrammen (d.h. Dendrogramme mit horizontalen Beschriftungen). Hier ist ein Beispiel (Beachten Sie den roten Streifen in der unteren rechten Ecke).Irgendetwas stimmt nicht mit den Abmessungen dessen, was rect.hclust() generiert, und ich weiß nicht, wie es funktioniert, um meine eigene Version schreiben zu können.

Ich bin für jeden Ratschlag dankbar edgePar oder rect.hclust() um richtig zu arbeiten oder um selbst schreiben zu können rect.hclust() Äquivalent.

AKTUALISIEREN

Seitdem ich diese Frage gestellt habe, habe ich verwendet getAnywhere(rect.hclust()) um den Funktionscode zu erhalten, der Parameter berechnet und zeichnet rect Objekt.Ich habe eine benutzerdefinierte Version dieser Funktion geschrieben, um horizontale und vertikale Blätter zu verarbeiten, und sie mit aufzurufen dendrapply().

Es gibt jedoch eine Art Clipping-Effekt, der einen Teil des Bildes entfernt rect.Bei horizontalen Blättern (Blätter, die auf der rechten Seite des Baums gezeichnet werden) ist der äußerste rechte Rand des rect entweder verschwindet oder ist dünner als die Randbreite der anderen drei Seiten des rect.Bei vertikalen Blättern (Blätter, die unten am Baum gezeichnet werden) ist die unterste Kante des rect leidet unter dem gleichen Anzeigeproblem.

Um signifikante Cluster zu markieren, habe ich die Breite reduziert rect so dass ich einen vertikalen roten Streifen zwischen den Spitzen der Clusterkanten und den (horizontalen) Blattbeschriftungen rendere.

Dadurch wird das Beschneidungsproblem beseitigt, es entsteht jedoch ein weiteres Problem, da der Abstand zwischen den Randspitzen des Clusters und den Blattbeschriftungen nur etwa sechs Pixel breit ist, worüber ich keine große Kontrolle habe.Dadurch wird die Breite des vertikalen Streifens begrenzt.

Das schlimmste Problem ist, dass die x-Koordinate, die markiert, wo der vertikale Streifen zwischen die beiden Elemente passen kann, ändert sich basierend auf der Breite des größeren Baums (par["usr"]), was wiederum davon abhängt, wie die Baumhierarchie letztlich strukturiert wird.

Ich habe eine „Korrektur“ oder besser gesagt einen Hack geschrieben, um dies anzupassen x Wert und die rect Breite für horizontale Bäume.Es funktioniert nicht immer konsistent, aber bei den Bäumen, die ich mache, scheint es nicht zu nahe an Kanten und Beschriftungen zu kommen (oder diese zu überlappen).

Letztendlich wäre es eine bessere Lösung, herauszufinden, wie man das zeichnet rect damit es nicht zu Clipping kommt.Oder eine konsistente Methode zur Berechnung des Spezifischen x Positionieren Sie sie zwischen den Baumkanten und den Beschriftungen für einen bestimmten Baum, um den Streifen richtig zu zentrieren und zu dimensionieren.

Ich wäre auch sehr an einer Methode interessiert, Kanten mit Farben oder Linienstilen zu kommentieren.

War es hilfreich?

Lösung

Sie haben also tatsächlich etwa fünf Fragen gestellt (5 +/- 3).Was das Schreiben Ihrer eigenen rect.hclust-ähnlichen Funktion betrifft, ist die Quelle in library/stats/R/identify.hclust.R wenn du es dir ansehen willst.

Ich habe selbst einen kurzen Blick darauf geworfen und bin mir nicht sicher, ob es das tut, was ich beim Lesen Ihrer Beschreibung vermutet habe – es scheint zu zeichnen mehrere Rechtecke, Auch die x Der Selektor scheint fest codiert zu sein, um die Tags horizontal zu trennen (was nicht das ist, was Sie wollen und es auch nicht gibt). y).

Ich komme wieder, aber in der Zwischenzeit können Sie (zusätzlich zum Betrachten der Quelle) versuchen, mehrere rect.hclust mit verschiedenen zu erstellen border= Farben und anders h= Werte, um zu sehen, ob ein Fehlermuster auftritt.

Aktualisieren

Ich hatte auch nicht viel Glück damit, darin herumzustochern.

Ein möglicher Kniff für das Ausschneiden wäre, die Beschriftungen mit nachgestellten Leerzeichen aufzufüllen und dann den Rand Ihres Rechtecks ​​leicht nach innen zu ziehen (die Idee dahinter ist, dass das Rechteck durch bloßes Einziehen aus der Beschneidungszone herausgeholt wird, aber die Enden der Beschriftungen überschrieben werden ).

Eine andere Idee wäre, das Rechteck mit einer durchscheinenden Farbe (niedriger Alphawert) zu füllen und so einen schattierten Bereich statt eines Begrenzungsrahmens zu erzeugen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top