基于R语言构建分类学信息的经典环形树状图求助
需求:基于MOTU分类路径构建层级分明的环形树状图
我熟悉R语言,需要构建经典的环形树状图,用于展示宏条形码数据(Multiple Operation Taxonomic Units, MOTUs)的分类路径(如界;门;纲;目;科;属;种)层级关系。
已尝试的方法及问题
我基于metabaR包的ggtaxplot函数逻辑,使用igraph包尝试了两种方法,效果都不理想:
- 方法一(ggraph实现):外观符合环形树的预期,但所有叶节点被强制放在同一层级,无法展示不同分类级别的差异
- 方法二(igraph+ggplot实现):分类层级结构正确,但线条呈现网络状,层级关系不够清晰
核心需求
不局限于igraph工具,希望使用ggplot类方法实现,方便后续添加标签、颜色等自定义元素。
测试数据及预处理代码
测试数据
path <- c("root@no rank:Eukaryota@superkingdom:Opisthokonta@clade:Fungi@kingdom:Fungi incertae sedis@no rank:Mucoromycota@phylum:Mortierellomycotina@subphylum:Mortierellomycetes@class:Mortierellales@order:Mortierellaceae@family:Mortierella@genus:unclassified Mortierella@no rank", "root@no rank:Eukaryota@superkingdom:Opisthokonta@clade:Fungi@kingdom:Dikarya@subkingdom:Ascomycota@phylum:saccharomyceta@clade:Pezizomycotina@subphylum:leotiomyceta@clade:sordariomyceta@clade:Sordariomycetes@class:Xylariomycetidae@subclass:Xylariales@order:unclassified Xylariales@no rank:Xylariales sp.@species", "root@no rank:Eukaryota@superkingdom:Opisthokonta@clade:Fungi@kingdom:Fungi incertae sedis@no rank:Mucoromycota@phylum:Mortierellomycotina@subphylum:Mortierellomycetes@class:Mortierellales@order:Mortierellaceae@family:Linnemannia@genus:Linnemannia zychae@species", "root@no rank:Eukaryota@superkingdom:Opisthokonta@clade:Fungi@kingdom:Fungi incertae sedis@no rank:Mucoromycota@phylum:Mortierellomycotina@subphylum:Mortierellomycetes@class:Mortierellales@order:Mortierellaceae@family", "root@no rank:Eukaryota@superkingdom:Opisthokonta@clade:Fungi@kingdom:Dikarya@subkingdom:Ascomycota@phylum:saccharomyceta@clade:Pezizomycotina@subphylum:leotiomyceta@clade:sordariomyceta@clade:Sordariomycetes@class:Hypocreomycetidae@subclass:Hypocreales@order", "root@no rank:Eukaryota@superkingdom:Opisthokonta@clade:Fungi@kingdom:Dikarya@subkingdom:Ascomycota@phylum:saccharomyceta@clade:Pezizomycotina@subphylum:leotiomyceta@clade:sordariomyceta@clade:Leotiomycetes@class:Helotiales@order", "root@no rank:Eukaryota@superkingdom:Opisthokonta@clade:Fungi@kingdom:Dikarya@subkingdom:Ascomycota@phylum:saccharomyceta@clade:Pezizomycotina@subphylum:leotiomyceta@clade:dothideomyceta@clade:Dothideomycetes@class:Pleosporomycetidae@subclass:Pleosporales@order", "root@no rank:Eukaryota@superkingdom:Opisthokonta@clade:Fungi@kingdom:Dikarya@subkingdom:Ascomycota@phylum:saccharomyceta@clade:Pezizomycotina@subphylum:leotiomyceta@clade:sordariomyceta@clade:Leotiomycetes@class:Helotiales@order" )
预处理代码
library(metabaR) library(magrittr) library(igraph) library(ggraph) # 格式化分类路径信息 sep.level = ":"; sep.info = "@" parse <- unname(taxoparser(path, sep.level, sep.info)) %>% lapply(X =., FUN = function(x){ x <- x[names(x) %in% c("kingdom", "phylum", "class", "order", "family", "genus", "species")]}) path <- sapply(parse, toString) parse <- strsplit(path, ", ") parse.mat <- do.call(rbind, lapply(parse, `length<-`, max(lengths(parse)))) # 构建边列表 edgelist <- NULL for (i in rev(2:ncol(parse.mat))) { idx <- which(!is.na(parse.mat[, i])) kid <- parse.mat[idx, i] parent <- parse.mat[idx, (i - 1)] kidfull <- apply(parse.mat[idx, 1:i, drop = F], 1, toString) parentfull <- apply(parse.mat[idx, 1:(i - 1), drop = F], 1, toString) edgelist <- rbind( edgelist, unique(cbind( parentfull, kidfull, parent, kid )) ) }
已尝试的两种方法代码及问题
方法一:ggraph实现
# 第一种尝试:ggraph mygraph <- graph_from_data_frame( edgelist[,c("parent", "kid")] ) ggraph(mygraph, layout = 'dendrogram', circular = TRUE) + geom_edge_elbow() + geom_node_point() + theme_void()
问题:所有叶节点处于同一层级,无法展示不同分类级别
方法二:igraph+ggplot实现
# 第二种尝试:igraph g <- igraph::graph.edgelist(edgelist[rev(1:nrow(edgelist)), c("parentfull", "kidfull")], directed = F) # 重命名节点 igraph::V(g)$name2 <- ifelse(igraph::V(g)$name %in% edgelist[, "parent"], igraph::V(g)$name, edgelist[match(igraph::V(g)$name, edgelist[, "kidfull"]), "kid"] ) # 提取节点坐标信息 coords <- layout_as_tree(g, root=1, circular = F, rootlevel = numeric(), mode = "out", flip.y = TRUE) colnames(coords) <- c("x", "y") vdf <- data.frame(as.data.frame(get.vertex.attribute(g)), coords) # 提取边信息 edf <- get.data.frame(g) edf$from.x <- vdf$x[match(edf$from, as.vector(vdf$name))] edf$from.y <- vdf$y[match(edf$from, as.vector(vdf$name))] edf$to.x <- vdf$x[match(edf$to, as.vector(vdf$name))] edf$to.y <- vdf$y[match(edf$to, as.vector(vdf$name))] ggplot(data = vdf, aes(x = .data$x, y = -.data$y)) + geom_segment( data = edf, aes( x = .data$from.x, xend = .data$to.x, y = -.data$from.y, yend = -.data$to.y ), size = 0.2, colour = "grey" ) + geom_point() + scale_color_viridis_c() + theme_void() + coord_polar() + geom_text(aes(label = .data$name2), color = "darkgrey", show.legend = FALSE, hjust = 1)
问题:线条呈网络状,层级关系不清晰
内容的提问来源于stack exchange,提问作者Keyvan
相关产品推荐
相关产品推荐

