我data.tree
在 R 中使用包,我有一棵像下面这样的树,其中只有叶节点有标签。我正在尝试分配作为后代列表的属性(我们可以假设树总是分叉的)。
tree <- read.tree(text = "((A,B),C);")
tree <- as.Node(tree)
print(tree)
levelName
1 4
2 ¦--5
3 ¦ ¦--A
4 ¦ °--B
5 °--C
所以我正在寻找的是这样的东西,除了节点4
属性应该是(A,B)
它所说的地方5
。
tree$Do(function(node) node$desc1 <- as.vector(sapply(node$children, function(x) x$name))[1],
traversal = "post-order", filterFun = isNotLeaf)
tree$Do(function(node) node$desc2 <- as.vector(sapply(node$children, function(x) x$name))[2],
traversal = "post-order", filterFun = isNotLeaf)
print(tree, "desc1", "desc2")
levelName desc1 desc2
1 4 5 C
2 ¦--5 A B
3 ¦ ¦--A
4 ¦ °--B
5 °--C
因此,我不仅需要子节点名称,还需要它以递归方式将后代名称保存为列表并在从提示到根时分配它们。
levelName desc1 desc2
1 4 (A,B) C
2 ¦--5 A B
3 ¦ ¦--A
4 ¦ °--B
5 °--C
大图:我最终需要遍历树并将这些列表传递给另一个函数doSomething( group1 = "C", group2 = c("A","B") )
,即将该函数的输出保存为内部节点的属性。
我得到的最接近的是这个递归函数,但它给出与上面相同的输出
getDescendant <- function(node) {
if(node$isLeaf == FALSE) {
result <- as.vector(sapply(node$children, function(x) x$name))
} else {
result <-sapply(node$children, getDescendant)
}
return(result)
}
print(tree, desc = getDescendant)
levelName desc
1 4 5, C
2 ¦--5 A, B
3 ¦ ¦--A
4 ¦ °--B
5 °--C
编辑:这是我要做的工作,但它不能推广到没有分叉的树。
tree <- read.tree(text = "((A,B),C);")
tree <- as.Node(tree)
########## Collect descendant clades for each node
get_descendants <- function(node) {
if(node$children[[1]]$isLeaf == TRUE && node$children[[2]]$isLeaf == TRUE) {
node$desc1 <- node$children[[1]]$name
node$desc2 <- node$children[[2]]$name
} else if(node$children[[1]]$isLeaf == FALSE && node$children[[2]]$isLeaf == FALSE) {
node$desc1 <- c(as.vector(node$children[[1]]$desc1), as.vector(node$children[[1]]$desc2))
node$desc2 <- c(as.vector(node$children[[2]]$desc1), as.vector(node$children[[2]]$desc2))
} else {
if(node$children[[1]]$isLeaf == TRUE && node$children[[2]]$isLeaf == FALSE) {
node$desc1 <- node$children[[1]]$name
node$desc2 <- c(as.vector(node$children[[2]]$desc1), as.vector(node$children[[2]]$desc2))
} else {
node$desc1 <- c(as.vector(node$children[[1]]$desc1), as.vector(node$children[[1]]$desc2))
node$desc2 <- node$children[[2]]$name
}
}
}
tree$Do(function(node) get_descendants(node), filterFun=isNotLeaf,
traversal = "post-order")
print(tree, "desc1", "desc2")
levelName desc1 desc2
1 4 A, B C
2 ¦--5 A B
3 ¦ ¦--A
4 ¦ °--B
5 °--C