Подмножества набора данных в виде отдельных дендрограмм, но на одном графике

Я знаю, что могу построить дендрограмму следующим образом

library(cluster)
d <- mtcars
d[,8:11] <- lapply(d[,8:11], as.factor)

gdist <- daisy(d, metric = c("gower"), stand = FALSE)
dendro <- hclust(gdist, method = "average")
plot(as.dendrogram(dendro))

Однако у меня есть некоторые группы, определенные (например, методом итеративной классификации), указанные как последний столбец в d

G <- c(1,2,3,3,4,4,5,5,5,5,1,2,1,1,2,4,1,3,4,5,1,7,4,3,3,2,1,1,1,3,5,6)
d$Group <- G

head(d)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb  Group
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4     1
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4     2
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1     3
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1     3
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2     4
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1     4

Я пытаюсь построить все дендрограммы вместе на одном графике с одинаковым масштабом. Группы, состоящие только из одного члена, также необходимо нанести на график. (группа 6 и 7)

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

layout(matrix(1:9, 3,3,byrow=TRUE))

gdist <- as.matrix(gdist)

N <- max(G)
for (i in 1:N){
  rc_tokeep <- row.names(subset(d, G==i))
  dis <- as.dist(gdist[rc_tokeep, rc_tokeep])
  dend <- hclust(dis, method = "average")
  plot(as.dendrogram(dend))
}

введите здесь описание изображения

Цикл выдает эту ошибку для последних двух групп. (6 и 7), имеющие только один член.

Error in hclust(dis, method = "average") : 
  must have n >= 2 objects to cluster

По сути, я не хочу воспроизводить такие сюжеты. Здесь также нанесены кластеры с одиночными членами.

введите здесь описание изображениявведите здесь описание изображения


person Crops    schedule 18.06.2014    source источник
comment
У меня возникла проблема с запуском вашего примера кода. С «gdist ‹- daisy (d, metric = c (gower), stand = FALSE)» я получаю предупреждения о том, что двоичная переменная (ы) 8, 9 обрабатывается как масштабированный интервал, а затем gdist является только вектором, а не двумерным, поэтому извлечение в цикле не работает.   -  person MrFlick    schedule 19.06.2014
comment
@MrFlick Я изменил порядковую и номинальную переменную, чтобы она учитывала d, и привела gdist к матрице. Теперь пример кода должен работать нормально.   -  person Crops    schedule 19.06.2014


Ответы (1)


Если вы хотите имитировать последние несколько графиков, вы можете сделать что-то вроде этого:

N <- max(G)
layout(matrix(c(0,1:N,0),nc=1))

gdist <- as.matrix(gdist)

for (i in 1:N){
    par(mar=c(0,3,0,7))
    rc_tokeep <- row.names(subset(d, G==i))
    if(length(rc_tokeep)>2){ #The idea is to catch the groups with one single element to plot them differently
        dis <- as.dist(gdist[rc_tokeep, rc_tokeep])
        dend <- hclust(dis, method = "average")
        plot(as.dendrogram(dend),horiz=TRUE,
                 xlim=c(.8,0),axes=FALSE) # giving the same xlim will scale all of them, here i used 0.8 to fit your data but you can change it to whatever
        }else{
            plot(NA,xlim=c(.8,0),ylim=c(0,1),axes=F,ann=F)
            segments(0,.5,.1,.5) #I don't know how you intend to compute the length of the branch in a group of 1 element, you might want to change that
            text(0,.5, pos=4,rc_tokeep,xpd=TRUE)
            }
}

В вашем примере это дает:

введите здесь описание изображения

Если вы хотите добавить масштаб, вы можете добавить сетку на все графики и шкалу на последний:

N <- max(G)
layout(matrix(c(0,1:N,0),nc=1))

gdist <- as.matrix(gdist)

for (i in 1:N){
    par(mar=c(0,3,0,7))
    rc_tokeep <- row.names(subset(d, G==i))
    if(length(rc_tokeep)>2){
        dis <- as.dist(gdist[rc_tokeep, rc_tokeep])
        dend <- hclust(dis, method = "average")
        plot(as.dendrogram(dend),horiz=TRUE,xlim=c(.8,0),xaxt="n",yaxt="n")
        abline(v=seq(0,.8,.1),lty=3) #Here the grid
        }else{
            plot(NA,xlim=c(.8,0),ylim=c(0,1),axes=F,ann=F)
            segments(0,.5,.1,.5)
            text(0,.5, pos=4,rc_tokeep,xpd=TRUE)
            abline(v=seq(0,.8,.1),lty=3) #Here the grid
            }
    }
axis(1,at=seq(0,.8,.1)) #Here the axis

введите здесь описание изображения

И, наконец, если вы хотите выровнять промежутки между различными ветвями на результирующем графике, вы можете использовать table(d$Group), чтобы получить количество членов каждой группы и использовать его в качестве высоты для каждого подграфика:

N <- max(G)

layout(matrix(c(0,1:7,0),nc=1), height=c(3,table(d$Group),3)) #Plus the height of the empty spaces.

gdist <- as.matrix(gdist)

for (i in 1:N){
    par(mar=c(0,3,0,7))
    rc_tokeep <- row.names(subset(d, G==i))
    if(length(rc_tokeep)>2){
        dis <- as.dist(gdist[rc_tokeep, rc_tokeep])
        dend <- hclust(dis, method = "average")
        plot(as.dendrogram(dend),horiz=TRUE,xlim=c(.8,0),xaxt="n",yaxt="n")
        abline(v=seq(0,.8,.1),lty=3)
        }else{
            plot(NA,xlim=c(.8,0),ylim=c(0,1),axes=F,ann=F)
            segments(0,.5,.1,.5)
            text(0,.5, pos=4,rc_tokeep,xpd=TRUE)
            abline(v=seq(0,.8,.1),lty=3)
            }
    }
axis(1,at=seq(0,.8,.1))

введите здесь описание изображения

person plannapus    schedule 19.06.2014