我的解决办法结束了被使用的the answer to a related SO question about dendrograms一个修改的版本的数据帧到Newick树字符串转换,然后读取所产生的字符串转换成使用phytools::read.newick
一个phylo
对象,在这一点,我可以使用ape::as.hclust
转换为hclust
对象(如果需要的话)。不错!
(略编辑)与其他解决方案,以便回答
注:这些功能似乎并没有发挥好与tibbles
,所以使用标准data.frames
代替。
df2newick <- function(df, innerlabel = FALSE){
traverse <- function(a, i, innerl){
if(i < (ncol(df))){
alevelinner <- as.character(
unique(df[which(as.character(df[,i]) == a), i + 1])
)
desc <- NULL
for(b in alevelinner)
desc <- c(desc, traverse(b, i + 1, innerl))
il <- NULL
if(innerl==TRUE)
il <- paste0(",", a)
(newickout <- paste("(", paste(desc,collapse = ","), ")", il,
sep=""))
}
else {
(newickout <- a)
}
}
alevel <- as.character(unique(df[,1]))
newick <- NULL
for(x in alevel)
newick <- c(newick, traverse(x, 1, innerlabel))
(newick <- paste("(", paste(newick, collapse = ","), ");", sep=""))
}
重现的实例
ex = structure(list(level.1 = c("1", "1", "1", "1", "1", "1", "1",
"1", "1", "1", "1", "1", "1"), level.2 = c("883", "883", "883",
"883", "883", "883", "883", "883", "1758", "883", "883", "883",
"883"), level.3 = c("2293", "2293", "2293", "2293", "2293", "2293",
"2293", "2293", "3240", "2293", "2293", "2293", "2293"), level.4 = c("3932",
"3932", "3932", "3932", "3932", "3932", "3932", "3932", "5139",
"5777", "3932", "3932", "3932"), level.5 = c("6056", "6056",
"6056", "6056", "6056", "6056", "6056", "6056", "7472", "8110",
"6056", "6056", "6056"), level.6 = c("8456", "8545", "8949",
"8456", "8545", "8456", "8545", "8545", "10385", "11023", "8545",
"8545", "8545"), level.7 = c("11525", "11635", "12084", "12297",
"12339", "12297", "12339", "12339", "13632", "14270", "12339",
"12339", "12339"), name = c("A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M")), class = "data.frame", .Names = c("level.1",
"level.2", "level.3", "level.4", "level.5", "level.6", "level.7",
"name"), row.names = c(NA, -13L))
treestring = df2newick(ex, innerlabel = FALSE)
library(phytools)
extree = collapse.singles(read.newick(text = treestring))
extree$node.label = head(names(ex), -1)
plot(extree, show.node.label = TRUE)