【问题标题】:R: How do you summarize data for both leafs and nodes in Data.Tree?R:你如何总结 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”,但未能使其工作。

【问题讨论】:

    标签: r recursion tree directory summarization


    【解决方案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。我以为你想要它作为一个更容易使用的矢量。我会更新我的答案。
    猜你喜欢
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多