在R中制作带有标签的水平树状图

23

我希望通过hclust函数的输出绘制一棵谱系树。我希望这个谱系树是水平排列而不是默认的垂直排列,可以通过以下方式实现(例如):

require(graphics)
hc <- hclust(dist(USArrests), "ave")
plot(hc)
我尝试使用as.dendrogram()函数,像这样使用plot(as.dendrogram(hc.poi),horiz=TRUE),但结果没有有意义的标签:

enter image description here

如果我使用plot(hc.poi,labels=c(...))而没有使用as.dendrogram(),我可以传递labels=参数,但现在树状图是垂直的而不是水平的。有没有办法同时水平排列树状图并指定用户自定义标签?谢谢!

更新:以USArrests数据集为例,假设我想要使用州名的前两个字母的缩写作为标签,这样我想要将labs传递到绘图函数中:

labs = substr(rownames(USArrests),1,2)

得到的结果是:

 [1] "Al" "Al" "Ar" "Ar" "Ca" "Co" "Co" "De" "Fl" "Ge" "Ha"
[12] "Id" "Il" "In" "Io" "Ka" "Ke" "Lo" "Ma" "Ma" "Ma" "Mi"
[23] "Mi" "Mi" "Mi" "Mo" "Ne" "Ne" "Ne" "Ne" "Ne" "Ne" "No"
[34] "No" "Oh" "Ok" "Or" "Pe" "Rh" "So" "So" "Te" "Te" "Ut"
[45] "Ve" "Vi" "Wa" "We" "Wi" "Wy"

我想知道你代码示例中的 hc.poi 是什么? - Nate Anderson
2个回答

27
为了在水平树状图中显示您定义的标签,一种解决方案是将数据框的行名称设置为新标签(所有标签应该是唯一的)。
require(graphics)
labs = paste("sta_",1:50,sep="") #new labels
USArrests2<-USArrests #new data frame (just to keep original unchanged)
rownames(USArrests2)<-labs #set new row names
hc <- hclust(dist(USArrests2), "ave")
par(mar=c(3,1,1,5)) 
plot(as.dendrogram(hc),horiz=T)

enter image description here

编辑 - 使用ggplot2的解决方案

labs = paste("sta_",1:50,sep="") #new labels
rownames(USArrests)<-labs #set new row names
hc <- hclust(dist(USArrests), "ave")

library(ggplot2)
library(ggdendro)

#convert cluster object to use with ggplot
dendr <- dendro_data(hc, type="rectangle") 

#your own labels (now rownames) are supplied in geom_text() and label=label
ggplot() + 
  geom_segment(data=segment(dendr), aes(x=x, y=y, xend=xend, yend=yend)) + 
  geom_text(data=label(dendr), aes(x=x, y=y, label=label, hjust=0), size=3) +
  coord_flip() + scale_y_reverse(expand=c(0.2, 0)) + 
  theme(axis.line.y=element_blank(),
        axis.ticks.y=element_blank(),
        axis.text.y=element_blank(),
        axis.title.y=element_blank(),
        panel.background=element_rect(fill="white"),
        panel.grid=element_blank())

enter image description here


谢谢,但我还是不明白怎么能够将用户指定的标签赋给水平树状图?你提供的例子里面有内置的标签,但我真的想要传递自己的标签... - alittleboy
请查看上面的更新。很抱歉我的数据示例难以在线发布,所以我只是编了一个标签向量,想要在水平树状图上展示。再次感谢! - alittleboy
@alittleboy 更新了我的解决方案。这个解决方案只在标签唯一的情况下才有效。 - Didzis Elferts
更改标签时,只需使用hc$labels <- labs即可,无需复制整个数据框。 - h2kyeong
我认为当OP说“你给出的示例具有内置标签”时,他的意思是存储在hc中的hclust对象已经具有其树叶的“标签”(如hclust文档所述)。此外,如果您使用的是stringdistmatrix而不是dist,请记住参数useNames(https://mran.microsoft.com/web/packages/stringdist/stringdist.pdf),它将每个字符串与字符串本身标记。 - Nate Anderson
@DidzisElferts,这太棒了!!!你应该将你的ggplot解决方案编写成一个小包(或者请求合并到,比如说,ggfortify中)。 - JelenaČuklina

27

通过使用 dendrapply ,您可以根据自己的喜好自定义您的树状图。

输入图片描述

colLab <- function(n) {
  if(is.leaf(n)) {
    a <- attributes(n)
    attr(n, "label") <- substr(a$label,1,2)             #  change the node label 
    attr(n, "nodePar") <- c(a$nodePar, lab.col = 'red') #   change the node color
  }
  n
}

require(graphics)
hc <- hclust(dist(USArrests), "ave")
clusDendro <- as.dendrogram(hc)
clusDendro <- dendrapply(clusDendro, colLab)
op <- par(mar = par("mar") + c(0,0,0,2))
plot(clusDendro,horiz=T)

是的,我很欣赏你的出色回答,并且已经为你的帖子点赞了。很抱歉我只能选择一个最终答案... - alittleboy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接