在R中删除树中没有孩子的兄弟姐妹

时间:2016-07-29 00:20:26

标签: r

我正在观察用户可以增长或崩溃的d3js树的更改。闪亮的ui将对树的更新作为展平的json返回到服务器(r)并映射到数据帧。

我想找到所有孩子都没有的兄弟姐妹,或者只找到有孩子并修剪孩子的兄弟姐妹

以下是此类数据框的示例

x=data.frame(cyl=c(4,4,4,6,6,8),vs=c(0,1,1,0,1,NA),am=c(NA,0,1,rep(NA,3)))

在这个例子中,我想从下面的这个树中删除ggplot / 8和ggplot / 4/0

tree

1 个答案:

答案 0 :(得分:0)

首先,您需要以更有效的方式表示您的树。您当前的表示形式(其中每一行似乎代表树中的一个分支)使其难以使用。更好的表示形式是 - 每个节点有一行,带有node_id(见下文)。你为整个树构建这个表。为“可见性”添加矢量/列,然后每次在节点上进行扩展/折叠时都不需要重新创建/过滤数据集(稍后解释)。因此,对于您的给定树,您的基本表示将如下所示:

A = matrix(0,nrow = nrow(tree),ncol=nrow(tree))
A[cbind(tree$parent_id,tree$node_id)] = 1

现在,要真正使用树,创建一个asjacency矩阵通常很有用。所以,如果你有N个节点(在我们的例子中为10),那么你得到一个N * N二进制矩阵,其中A(i,j)= 1 iff i是j的父节点。您可以使用以下代码从上面创建邻接矩阵:

B = A + A%*%A + A%*%A%*%A  #that should be enough here, more generally you'd need some looping to add enough powers of A
B0 = 0+ (B>0)

现在,你真正需要的是一个“优先矩阵”,一个矩阵B,其中B(i,j)= 1 iff j是i的后果。你可以通过将A乘以它自己(矩阵乘法)并加上A的幂来得到它。如果有一个d级别的树A ^(d + 1)= 0,那么就不需要超越它了。这样:

prune_at = function(node_id,decenedency,current_visibility) {
    to_prune = which(decendency[node_id,]>0)
    new_visibility = current_visibility
    new_visibility[to_prune] = F
    new_visibility
}

# for example:
pruned = prune_at(2,B0,tree$visibility)

现在。要修剪节点i处的树,您需要以下内容:

expand_at = function(node_id,adjacency,current_visibility) {
    new_visibility = current_visibility
    if(current_visibility[node_id]==T) {
        to_expand = which(adjacency[node_id,]==1)
        new_visibility[to_expand] = T
    }
    new_visibility
}

#example
expand_at(2,A,pruned)

要展开可见节点,以便您看到其子节点:

{{1}}

总而言之 - 您为整个数据集创建一次表示。那么你所需要的只是玩“可见性”向量,它从一个操作变为另一个操作,说明哪些节点是可见的。

我希望这是有道理的。