2016-12-09 2 views
1

Идея состоит в объединении пакетов R ClustOfVar и ggdendro, чтобы дать визуальное резюме переменной кластеризации.R: регулировка высоты ggplot для кластеризации dendrogram

Когда в данных имеется несколько столбцов, результат довольно хорош, за исключением того, что есть области, которые не покрыты (как показано на рисунке ниже). Использование mtcars, например:

library(plyr) 
library(ggplot2) 
library(gtable) 
library(grid) 
library(gridExtra) 

library(ClustOfVar) 
library(ggdendro) 

fit = hclustvar(X.quanti = mtcars) 

labels = cutree(fit,k = 5) 

labelx = data.frame(Names=names(labels),group = paste("Group",as.vector(labels)),num=as.vector(labels)) 

p1 = ggdendrogram(as.dendrogram(fit), rotate=TRUE) 

df2<-data.frame(cluster=cutree(fit, k =5), states=factor(fit$labels,levels=fit$labels[fit$order])) 
df3<-ddply(df2,.(cluster),summarise,pos=mean(as.numeric(states))) 

p2 = ggplot(df2,aes(states,y=1,fill=factor(cluster)))+geom_tile()+ 
    scale_y_continuous(expand=c(0,0))+ 
    theme(axis.title=element_blank(), 
     axis.ticks=element_blank(), 
     axis.text=element_blank(), 
     legend.position="none")+coord_flip()+ 
    geom_text(data=df3,aes(x=pos,label=cluster)) 
gp1<-ggplotGrob(p1) 
gp2<-ggplotGrob(p2) 
maxHeight = grid::unit.pmax(gp1$heights[2:5], gp2$heights[2:5]) 
gp1$heights[2:5] <- as.list(maxHeight) 
gp2$heights[2:5] <- as.list(maxHeight) 
grid.arrange(gp2, gp1, ncol=2,widths=c(1/6,5/6)) 

enter image description here

Когда есть большое количество столбцов, возникает еще одна проблема. То есть высота части цветных плиток не соответствует высоте дендрограммы.

library(ClustOfVar) 
library(ggdendro) 
X = data.frame(mtcars,mtcars,mtcars,mtcars,mtcars,mtcars) 

fit = hclustvar(X.quanti = X) 

labels = cutree(fit,k = 5) 

labelx = data.frame(Names=names(labels),group = paste("Group",as.vector(labels)),num=as.vector(labels)) 

p1 = ggdendrogram(as.dendrogram(fit), rotate=TRUE) 

df2<-data.frame(cluster=cutree(fit, k =5), states=factor(fit$labels,levels=fit$labels[fit$order])) 
df3<-ddply(df2,.(cluster),summarise,pos=mean(as.numeric(states))) 

p2 = ggplot(df2,aes(states,y=1,fill=factor(cluster)))+geom_tile()+ 
    scale_y_continuous(expand=c(0,0))+ 
    theme(axis.title=element_blank(), 
     axis.ticks=element_blank(), 
     axis.text=element_blank(), 
     legend.position="none")+coord_flip()+ 
    geom_text(data=df3,aes(x=pos,label=cluster)) 
gp1<-ggplotGrob(p1) 
gp2<-ggplotGrob(p2) 
maxHeight = grid::unit.pmax(gp1$heights[2:5], gp2$heights[2:5]) 
gp1$heights[2:5] <- as.list(maxHeight) 
gp2$heights[2:5] <- as.list(maxHeight) 
grid.arrange(gp2, gp1, ncol=2,widths=c(1/6,5/6)) 

enter image description here

@Sandy Muspratt фактически предоставил отличное решение для этой IF мы имеем R модернизированный до версии 3.3.1. R: ggplot slight adjustment for clustering summary

Но поскольку я не могу изменить версию R, развернутую на корпоративном сервере, мне интересно, есть ли другой способ обхода, который может согласовать эти две части.

+0

ли [ранняя версия] (http://stackoverflow.com/revisions/33358320/1) Работа для вас? – Axeman

+0

Да, спасибо. – John

ответ

3

Насколько я могу судить, ваш код не за горами. Проблема в том, что вы пытаетесь сопоставить непрерывную шкалу с дискретным масштабом при объединении двух графиков. Также представляется, что ggdendrogram() добавляет дополнительное пространство к оси y.

library(plyr) 
library(ggplot2) 
library(gtable) 
library(grid) 
library(gridExtra) 

library(ClustOfVar) 
library(ggdendro) 

# Data 
X = data.frame(mtcars,mtcars,mtcars,mtcars,mtcars,mtcars) 

# Cluster analysis 
fit = hclustvar(X.quanti = X) 

# Labels data frames 
df2 <- data.frame(cluster = cutree(fit, k =5), 
    states = factor(fit$labels, levels = fit$labels[fit$order])) 
df3 <- ddply(df2, .(cluster), summarise, pos = mean(as.numeric(states))) 

# Dendrogram 
# scale_x_continuous() for p1 should match scale_x_discrete() from p2 
# scale_x_continuous strips off the labels. I grab them from df2 
# scale _y_continuous() puts a little space between the labels and the dendrogram 
p1 <- ggdendrogram(as.dendrogram(fit), rotate = TRUE) + 
    scale_x_continuous(expand = c(0, 0.5), labels = levels(df2$states), breaks = 1:length(df2$states)) + 
    scale_y_continuous(expand = c(0.02, 0)) 

# Tiles and labels 
p2 <- ggplot(df2,aes(states, y = 1, fill = factor(cluster))) + 
    geom_tile() + 
    scale_y_continuous(expand = c(0, 0)) + 
    scale_x_discrete(expand = c(0, 0)) + 
    geom_text(data = df3, aes(x = pos, label = cluster)) + 
    coord_flip() + 
    theme(axis.title = element_blank(), 
     axis.ticks = element_blank(), 
     axis.text = element_blank(), 
     legend.position = "none") 

# Get the ggplot grobs 
gp1 <- ggplotGrob(p1) 
gp2 <- ggplotGrob(p2) 

# Make sure the heights match 
maxHeight <- unit.pmax(gp1$heights, gp2$heights) 
gp1$heights <- as.list(maxHeight) 
gp2$heights <- as.list(maxHeight) 

# Combine the two plots 
grid.arrange(gp2, gp1, ncol = 2,widths = c(1/6, 5/6)) 

enter image description here

Смежные вопросы