3

Je souhaite visualiser à quel point est un algorithme de clustering (avec certaines métriques de distance). J'ai des échantillons et leurs classes correspondantes. Pour visualiser, je regroupe et je souhaite colorier les branches d'un dendrogramme par les éléments du cluster. La couleur sera la couleur les plus éléments dans le cluster hiérarchique correspondent à (données par les données \ classes). Exemple: Si mon algorithme de clustering a choisi les index 1,21,24 pour être un certain cluster (à un certain niveau) et que j'ai un fichier csv contenant un numéro de classe dans chaque ligne correspondant à disons 1,2,1 . Je veux que ce bord à colorer 1.Comment colorier des branches dans R dendogram par l'une fonction des classes qu'il contient?

Exemple de code:

require(cluster) 
suppressPackageStartupMessages(library(dendextend)) 
dir <- 'distance_metrics/' 
filename <- 'aligned.csv' 
my.data <- read.csv(paste(dir, filename, sep=""), header = T, row.names = 1) 
my.dist <- as.dist(my.data) 
real.clusters <-read.csv("clusters", header = T, row.names = 1) 
clustered <- diana(my.dist) 
# dend <- colour_branches(???dend, max(real.clusters)???) 
plot(dend) 

EDIT: un autre exemple code partiel

dir <- 'distance_metrics/' # csv in here contains a symmetric matrix 
clust.dir <- "clusters/" #csv in here contains a column vector with classes 
my.data <- read.csv(paste(dir, filename, sep=""), header = T, row.names = 1) 
filename <- 'table.csv' 
my.dist <- as.dist(my.data) 
real.clusters <-read.csv(paste(clust.dir, filename, sep=""), header = T, row.names = 1) 
clustered <- diana(my.dist) 
dnd <- as.dendrogram(clustered) 
+0

Je vois déjà que je créé une façon de le faire en utilisant 'color_branches'. S'il vous plaît voir ma réponse. –

Répondre

1

Les deux noeuds et les attributs de couleur pointe peuvent être définies de manière récursive sur des objets « dendrogramme » (qui sont juste profondément imbriquées) en utilisant des listes dendrapply. Le package cluster comporte également une méthode as.dendrogram pour les objets de classe "diana", de sorte que la conversion entre les types d'objet est transparente. Utilisation de votre cluster diana et emprunter un code de l'exemple de l'iris @Edvardoss, vous pouvez créer le dendrogramme de couleur comme suit:

library(cluster) 
set.seed(999) 
iris2 <- iris[sample(x = 1:150,size = 50,replace = F),] 
clust <- diana(iris2) 
dnd <- as.dendrogram(clust) 

## Duplicate rownames aren't allowed, so we need to set the "labels" 
## attributes recursively. We also label inner nodes here. 
rectify_labels <- function(node, df){ 
    newlab <- df$Species[unlist(node, use.names = FALSE)] 
    attr(node, "label") <- (newlab) 
    return(node) 
} 
dnd <- dendrapply(dnd, rectify_labels, df = iris2) 

## Create a color palette as a data.frame with one row for each spp 
uniqspp <- as.character(unique(iris$Species)) 
colormap <- data.frame(Species = uniqspp, color = rainbow(n = length(uniqspp))) 
colormap[, 2] <- c("red", "blue", "green") 
colormap 

## Now color the inner dendrogram edges 
color_dendro <- function(node, colormap){ 
    if(is.leaf(node)){ 
    nodecol <- colormap$color[match(attr(node, "label"), colormap$Species)] 
    attr(node, "nodePar") <- list(pch = NA, lab.col = nodecol) 
    attr(node, "edgePar") <- list(col = nodecol) 
    }else{ 
    spp <- attr(node, "label") 
    dominantspp <- levels(spp)[which.max(tabulate(spp))] 
    edgecol <- colormap$color[match(dominantspp, colormap$Species)] 
    attr(node, "edgePar") <- list(col = edgecol) 
    } 
    return(node) 
} 
dnd <- dendrapply(dnd, color_dendro, colormap = colormap) 

## Plot the dendrogram 
plot(dnd) 

enter image description here

+1

y a-t-il une manière générique de ne pas spécifier les couleurs par mots (et donc de ne pas restreindre à un nombre prédéfini de classes)? – borgr

+0

Bien sûr, vous pouvez simplement utiliser le format hexadécimal RVB "#RRGGBB" pour spécifier n'importe quelle couleur dans le spectre. Par exemple, essayez de remplacer 'c (" red "," blue "," green ")' ci-dessus par 'c (" # B44682 "," # 82B446 "," # 4682B4 ")'. –

+0

mais cela est encore à la main, je ne peux pas utiliser l'arc-en-ciel ou quelque chose sans coder en dur les noms de couleurs (en mots ou en rgb) – borgr

0

il y a des soupçons qui ont mal compris la question mais je vais essayer de réponse: de mes objectifs précédents ont été réécrits par l'exemple de l'iris

clrs <- rainbow(n = 3) # create palette 
clrs <- clrs[iris$Species] # assign colors 
plot(x = iris$Sepal.Length,y = iris$Sepal.Width,col=clrs) # simple test colors 
# cluster 
dt <- cbind(iris,clrs) 
dt <- dt[sample(x = 1:150,size = 50,replace = F),] # create short dataset for visualization convenience 
empty.labl <- gsub("."," ",dt$Species) # create a space vector with length of names intended for reserve place to future text labels 
dst <- dist(x = scale(dt[,1:4]),method = "manhattan") 
hcl <- hclust(d = dst,method = "complete") 
plot(hcl,hang=-1,cex=1,labels = empty.labl, xlab = NA,sub=NA) 
dt <- dt[hcl$order,] # sort rows for order objects in dendrogramm 
text(x = seq(nrow(dt)), y=-.5,labels = dt$Species,srt=90,cex=.8,xpd=NA,adj=c(1,0.7),col=as.character(dt$clrs)) 

result

+0

Merci pour la réponse, mais je cherche des colorations sur les clusters \ edges \ lines. Non seulement sur les noms ticks \ label. Les questions sont de savoir comment choisir les colorants en utilisant le nom des étiquettes (par exemple la couleur par la couleur de l'étiquette la plus fréquente dans le cluster) – borgr

+0

peut être utile: [link] (https://stackoverflow.com/a/23260016/5090082) – Edvardoss

1

La fonction que vous recherchez est color_brances du paquet R dendextend, en utilisant les groupes d'arguments et col. Voici un exemple (basé sur l'exemple de Shaun Wilkinson):

library(cluster) 
set.seed(999) 
iris2 <- iris[sample(x = 1:150,size = 50,replace = F),] 
clust <- diana(iris2) 
dend <- as.dendrogram(clust) 

temp_col <- c("red", "blue", "green")[as.numeric(iris2$Species)] 
temp_col <- temp_col[order.dendrogram(dend)] 
temp_col <- factor(temp_col, unique(temp_col)) 

library(dendextend) 
dend %>% color_branches(clusters = as.numeric(temp_col), col = levels(temp_col)) %>% 
    set("labels_colors", as.character(temp_col)) %>% 
    plot 

enter image description here

+0

Je pensais que c'était la bonne solution mais ensuite je l'ai essayé sur des données réelles et remarqué, il s'arrête quand le cluster n'est pas fait d'un "vrai cluster". comment changeriez-vous la couleur pour être la couleur du mose représenté sous forme de groupe réel sous le bord au lieu de par le seul représenté?les données de la vie réelle ont du bruit et ne se divisent donc pas si bien. ou ai-je oublié quelque chose? – borgr

+0

Salut, pourriez-vous produire un exemple simple pour illustrer le problème? (Je suppose que c'est un bug) Si oui, vous pouvez le poster sur github.com/talgalili/dendextend/issues –

+0

vous pouvez le voir aussi dans votre exemple, certaines des meilleures branches sont noires, j'ai juste eu plus de noirs. – borgr