Cluster en Heatmap à dendrogrammes

En langage R

L'essentiel de cette page !

Les heatmap sont une façon aboutie d'illustrer des clusters. Ils permettent de visualiser l'ensemble des résultats et individus, de les regrouper par catégories et d'établir le lien entre les paramètres qui jouent sur ces catégories.

La fonction heatmap() est par défaut sur R mais il y en a d'autres.

Pour voir les méthodes de classification - cliquer sur ce lien.

1- Tracer la heatmap

1.1- Données nécessaires à l'exemple

Partons du même jeu habituel : des données simulées d'analyses sanguines pour différents patients (ici, 20 patients)

Pour simuler ces valeurs : copier-coller le code dans la console.

#Simulation d'un jeu de données à 3 catégories et 5 variables

l_a <- 6 ; l_b <- 8  ; l_c <- 4

# Glycémie

x_a <- rnorm(l_a,1,0.2);x_b <- rnorm(l_b,1.1,0.23);x_c <- rnorm(l_c,1,0.3);x <- c(x_a,x_b,x_c)

# Calcémie

y_a <- runif(l_a,2.2,2.6) ;y_b <- rnorm(l_b,2.3,0.5) ;y_c <- rpois(l_c,22)/10 ;y <- c(y_a,y_b,y_c)

# Protéine C-Réactive 6 mg/L

z_a <- rnorm(l_a/3,6,2) ;z_a <- c(z_a,rnorm(l_a/3,20,15));z_a <- c(z_a,rnorm(l_a/3,6,4)); z_b <-rnorm(l_b,2.5,0.5) ;z_c <- rpois(l_c,50);z <- abs(c(z_a,z_b,z_c))

# TSH 0.4 à 4 mUI/l 

w_a <- rnorm(l_a/2,2,1) ;w_a <- c(w_a,rnorm(l_a/2,2,1.1));w_a <- sort(w_a);w_b <- sort(abs(rnorm(l_b,1,2))); w_c <- rev(sort(abs(rnorm(l_c,4,1))));w <- abs(c(w_a,w_b,w_c))

# HDL 0.4 à 0.5

v_a <- rpois(l_a,50)/100;v_b <- sort(rpois(l_b,50)/100);v_c <- sort(rpois(l_c,50)/100)+0.2;v <- c(v_a,v_b,v_c)

# Catégories

categories<-c(rep("A",l_a),rep("B",l_b),rep("C",l_c))

# Compilation dans un tableau data.frame

analyses<- data.frame(categories,x,y,z,w,v); colnames(analyses) <- c("Catégories","Glycémie","Calcémie","Protéine C-Réactive","TSH","HDL");

head(analyses)

1.2- Réaliser la heatmap avec dendrogramme

# Compiler l'ensemble des données dans une matrice

analyses_scaled <- as.matrix(scale(analyses[,-1]))

# Tracer la heatmap

heatmap(analyses_scaled, Colv=F, scale='none')

Ou encore, en changeant la couleur

# Définir une palette de transition du rouge vers le vert

# 10 gammes de couleurs

palette <- colorRampPalette(c("red","green"))(10)

# Tracer

heatmap(analyses_scaled, Colv=T, scale='none', col=palette,cexCol=0.6)

Remarque : on peut aussi remplacer la palette par col=gray.colors(100) si l'on souhaite avoir une heatmap en niveau de gris (utile pour les impressions).

heatmap présente de nombreux paramètres dont voici quelques uns :

Pour aller plus loin dans la mise en forme, allons voir plus bas dans la page.

Ce cluster permet de regrouper les patients. On voit ainsi apparaître des frontières horizontales qui confirment l'existence de 3 catégories de patients (dendrogramme de gauche).

Il apparait aussi que protéine-C TSH et HDL agissent en synergie d'un côté contre glycémie et calcémie.

2- Aller plus loin dans la mise en forme

Changer la méthode de calcul dans la constitution du cluster et l'établissement des distances

palette <- colorRampPalette(c("yellow","pink","#9E1B5D"))(20)

analyses_scaled <- as.matrix(scale(analyses[,-1]))

# Heatmap par défaut

heatmap(analyses_scaled,Colv=T, scale='none', col=palette,cexCol=0.6)

# Heatmap en imposant la fonction hclust pour faire le cluster et sa method "ward.D2"

heatmap(analyses_scaled, Colv=T,hclustfun=function(x) hclust(x, method="ward.D2"), scale='none', col=palette,cexCol=0.6)


heatmap par défaut

La méthode par défaut n'a pas su identifier les 3 catégories de 4, 6 et 8 individus.

heatmap avec la méthode hclust ward.D2

En changeant la méthode, on a réussi a identifier 3 catégories de 4, 7 et 7 individus : on se rapproche de la réalité.Pour identifier d'autres méthodes hclust ou dist.

Pour aller plus loin dans la mise en forme

On peut colorer les parties du dendrogramme, légender...etc.

Il suffit d'accéder à l'aide de la fonction heatmap() en tapant dans la console :

?heatmap

3- Extraire les résultats de clustering de la heatmap

La heatmap permet d'aller loin, elle confirme aussi les paramètres qui ont la plus forme influence et leurs rôles synergiques : on va ainsi retrouver des résultats équivalents à ceux qu'on aurait eu en faisant une analyse en composante principale (ACP).

Récupérer les 2 clusters intrinsèques à la heatmap

# cluster rows - Cluster classique regroupant les individus

hc.rows <- hclust(dist(analyses_scaled), method="ward.D2")

plot(hc.rows,sub="",xlab="",main="Clusters des individus")

# clusters columns - Cluster sur les paramètres et leur façon de jouer sur la diversité des individus

hc.cols <- hclust(dist(t(analyses_scaled)), method="ward.D2")

plot(hc.cols,sub="",xlab="",main="Clusters des paramètres")

Cluster des 20 individus

On retrouve clairement les 3 catégories mais une erreur de cah fait qu'on ne retrouve pas la répartition simulée de 4, 8 et 6 individus (mais presque !)

Cluster des paramètres

On voit que ce qui joue sur la séparation des individus, c'est surtout l'analyse de la Protéine-C-réactive et le HDL.

Height sans être une corrélation traduit ici un équivalent.

Afficher les heatmaps de chaque catégories

palette <- colorRampPalette(c("black","purple","#4B1B9E","orange"))(30)

heatmap(analyses_scaled, Colv=as.dendrogram(hc.cols), scale='none', col=palette,cexCol=0.6)

# Classe 1

heatmap(analyses_scaled[cutree(hc.rows,k=3)==1,], Colv=as.dendrogram(hc.cols), scale='none', col=palette,cexCol=0.6)

# Classe 2

heatmap(analyses_scaled[cutree(hc.rows,k=3)==2,], Colv=as.dendrogram(hc.cols), scale='none', col=palette,cexCol=0.6)

# Classe 3

heatmap(analyses_scaled[cutree(hc.rows,k=3)==3,], Colv=as.dendrogram(hc.cols), scale='none', col=palette,cexCol=0.6)

Ci-dessus, le cluster général des 20 individus.

On peut voir sur le côté, à droite, les heatmaps des 3 catégories d'individus.

4- Quand on veut visualiser les données manquantes et aller plus loin dans la mise en forme

Il faut alors passer à la fonction heatmap.2 de {gplots}.

heatmap.2(

  analyses_scaled,

  trace="none",

  Colv = NA,

  na.color = "black"

)