R:你如何总结 Data.Tree 中叶子和节点的数据?

Posted

技术标签:

【中文标题】R:你如何总结 Data.Tree 中叶子和节点的数据?【英文标题】:R: How do you summarize data for both leafs and nodes in Data.Tree? 【发布时间】:2018-02-17 04:52:15 【问题描述】:

我正在使用 data.tree 结构来汇总文件夹中的各种信息。在每个文件夹中我有许多文件(Value),我需要为每个文件夹做的就是总结文件夹+所有子文件夹包含多少个文件。

示例数据:

library(data.tree)
data <- data.frame(pathString = c("MainFolder",
                                  "MainFolder/Folder1",
                                  "MainFolder/Folder2",
                                  "MainFolder/Folder3",
                                  "MainFolder/Folder1/Subfolder1",
                                  "MainFolder/Folder1/Subfolder2"),
                   Value = c(1,1,5,2,4,10))
tree <- as.Node(data, Value)
print(tree, "Value")
               levelName Value
1 MainFolder             1
2  ¦--Folder1            1
3  ¦   ¦--Subfolder1     4
4  ¦   °--Subfolder2    10
5  ¦--Folder2            5
6  °--Folder3            2

我目前对这个问题的解决方案非常缓慢:

# Function to sum up file counts pr folder + subfolders
total_count <- function(node) 
  results <- sum(as.data.frame(print(node, "Value"))$Value)
  return(results)


# Summing up file counts pr folder + subfolders
tree$Do(function(node) node$Value_by_folder <- total_count(node))


# Results
print(tree, "Value", "Value_by_folder")
           levelName Value Value_by_folder
1 MainFolder             1              23
2  ¦--Folder1            1              15
3  ¦   ¦--Subfolder1     4               4
4  ¦   °--Subfolder2    10              10
5  ¦--Folder2            5               5
6  °--Folder3            2               2

您对如何更有效地执行此操作有什么建议吗?我一直在尝试构建一个递归方法,并在节点上使用函数“isLeaf”和“children”,但未能使其工作。

【问题讨论】:

【参考方案1】:

这是一种有效的方法。它使用 data.tree API 并将值存储在树中:

MyAggregate <- function(node) 
  if (node$isLeaf) return (node$Value)
  sum(Get(node$children, "Value_by_folder")) + node$Value


tree$Do(function(node) node$Value_by_folder <- MyAggregate(node), traversal = "post-order")

【讨论】:

谢谢,我今天将测试两个答案。这个看起来最干净,但它不是 return(sum(Get(node$children, "Value_by_folder")) + node$Value) 有什么原因吗? 不,是一样的。 R 函数总是返回最后一个值。 @EsbenEickhardt 不确定您对清洁器的定义,但我认为这应该更慢。您能告诉我们在您的更大数据集上进行基准测试的结果吗? @F.Privé 啊,对不起,我说得更清楚了,这个解决方案使用了 data.tree 包中的函数,而不是 R 基础函数。 'force' 和 ' @EsbenEickhardt 在您感兴趣的部分(我的编辑)中,我不使用任何这些。【参考方案2】:

你可以这样做:

get_value_by_folder <- function(tree) 

  res <- rep(NA_real_, tree$totalCount)

  i <- 0
  myApply <- function(node) 
    i <<- i + 1
    force(k <- i)
    res[k] <<- node$Value + `if`(node$isLeaf, 0, sum(sapply(node$children, myApply)))
  

  myApply(tree)
  res

force 很重要,因为对 R 的惰性求值会与您要填写 res 的顺序混淆。

你会得到:

> get_value_by_folder(tree)
[1] 23 15  4 10  5  2

编辑:如果您想直接将其填充到树中。

get_value_by_folder2 <- function(tree) 

  myApply <- function(node) 
    node$Value_by_folder <- node$Value + `if`(node$isLeaf, 0, sum(sapply(node$children, myApply)))
  

  myApply(tree)
  tree


> print(get_value_by_folder2(tree), "Value", "Value_by_folder")
           levelName Value Value_by_folder
1 MainFolder             1              23
2  ¦--Folder1            1              15
3  ¦   ¦--Subfolder1     4               4
4  ¦   °--Subfolder2    10              10
5  ¦--Folder2            5               5
6  °--Folder3            2               2

注意类是一个环境,所以原来的tree被修改了。

> print(tree, "Value", "Value_by_folder")
           levelName Value Value_by_folder
1 MainFolder             1              23
2  ¦--Folder1            1              15
3  ¦   ¦--Subfolder1     4               4
4  ¦   °--Subfolder2    10              10
5  ¦--Folder2            5               5
6  °--Folder3            2               2

【讨论】:

这会保存树中的值吗? @EsbenEickhardt Nop。我以为你想要它作为一个更容易使用的矢量。我会更新我的答案。

以上是关于R:你如何总结 Data.Tree 中叶子和节点的数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何判断EasyUi中treegride的某一节点是不是叶子节点

如何在 R 中创建单个分支实体/死胡同的外部叶子列表?

1302. 层数最深叶子节点的和

已知树中非叶子节点的度数和数量,如何计算树中叶子节点的个数?

C++如何求二叉树中一个结点到根节点的路径?

如何用 R 中的值可视化 data.tree?