Ho generato this dendrogram utilizzando le funzioni R hclust()
, as.dendrogram()
e plot.dendrogram()
.Come posso colorare i bordi o disegnare correttamente i rec in un dendogramma R?
Ho usato la funzione dendrapply()
e una funzione locale per colorare le foglie, che funziona bene.
devo risultati di un test statistico che indicano se un insieme di nodi (ad esempio cluster di "_+v\_stat5a\_01_
" e "_+v\_stat5b\_01_
" nell'angolo inferiore destro dell'albero) sono significative o importanti.
Ho anche una funzione locale che posso utilizzare con dendrapply()
che trova il nodo esatto nel mio dendrogramma che contiene foglie significative.
desidero o (seguendo l'esempio):
- colori i bordi che uniscono "
_+v\_stat5a\_01_
" e "_+v\_stat5b\_01_
"; o, - Disegnare una
rect()
intorno "_+v\_stat5a\_01_
" e "_+v\_stat5b\_01_
"
Ho la seguente funzione locale (i dettagli dei "nodi-in-leafList match-nodi-in-clusterList" condizione aren 't importante, ma che mette in luce i nodi significativi):
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
}
}
}
}
da questa if
blocco, ho provato a chiamare dendrapply(n, markEdges)
, ma questo non ha funzionato:
markEdges <<- function (n) {
a <- attributes(n)
attr(n, "edgePar") <- c(a$edgePar, list(lty=3, col="red"))
}
Nel mio esempio ideale, i bordi che collegano "_+v\_stat5a\_01_
" e "_+v\_stat5b\_01_
" sarebbero tratteggiati e di colore rosso.
ho anche provato ad utilizzare rect.hclust()
all'interno di questo blocco if
:
ma <- match(leafList, orderedLabels)
rect.hclust(scoreClusterObj, h = a$height, x = c(min(ma), max(ma)), border = 2)
Ma il risultato non funziona con dendrogrammi orizzontali (cioè dendrogrammi con etichette orizzontali). Here is an example (notare la striscia rossa nell'angolo in basso a destra). Qualcosa non è corretto sulle dimensioni di ciò che genera rect.hclust()
, e non so come funziona, per essere in grado di scrivere la mia versione.
Apprezzo qualsiasi suggerimento per ottenere edgePar
o rect.hclust()
per funzionare correttamente, o per essere in grado di scrivere il mio equivalente rect.hclust()
.
UPDATE
Da questa domanda, ho usato getAnywhere(rect.hclust())
per ottenere il codice funzionale che calcola i parametri e disegna l'oggetto rect
. Ho scritto una versione personalizzata di questa funzione per gestire le foglie orizzontali e verticali e chiamarla con dendrapply()
.
Tuttavia, è presente un tipo di effetto di ritaglio che rimuove parte dello rect
.Per le foglie orizzontali (foglie disegnate sul lato destro dell'albero), il bordo più a destra di rect
scompare o è più sottile della larghezza del bordo degli altri tre lati di rect
. Per le foglie verticali (foglie disegnate sul fondo dell'albero), il bordo inferiore dello rect
soffre dello stesso problema di visualizzazione.
Ciò che avevo fatto per contrassegnare cluster significativi è ridurre la larghezza dello rect
in modo da rendere una striscia rossa verticale tra le punte dei bordi del cluster e le etichette foglia (orizzontali).
Questo elimina il problema di ritaglio, ma introduce un altro problema, in quanto lo spazio tra i bordi del bordo del cluster e le etichette foglia è largo solo sei pixel, cosa su cui non ho molto controllo. Questo limita la larghezza della striscia verticale.
Il problema peggiore è che il -coordinate x
che segna dove la striscia verticale può andare bene tra i due elementi cambierà in base alla larghezza della struttura più grande (par["usr"]
), che a sua volta dipende da come la gerarchia della struttura finisce essere strutturato.
Ho scritto una "correzione" o, meglio definita, un trucco per regolare questo valore x
e la larghezza rect
per alberi orizzontali. Non sempre funziona in modo coerente, ma per gli alberi che sto creando sembra non avvicinarsi troppo (o sovrapporsi) ai bordi e alle etichette.
In definitiva, una soluzione migliore sarebbe scoprire come disegnare il rect
in modo che non ci sia il clipping. O un modo coerente per calcolare la specifica posizione x
tra i bordi dell'albero e le etichette per ogni albero dato, in modo da centrare e ridimensionare correttamente la striscia.
Sarei anche molto interessato a un metodo per annotare i bordi con colori o stili di linea.
Bene, ho scritto una funzione rect.dendrogram nel pacchetto dendextend.C'è anche una funzione per colorare i rami in base alle etichette che contengono chiamati 'branches_attr_by_labels'. –