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

问题描述:

我正在使用data.tree结构来汇总文件夹中的各种信息。在每个文件夹中,我有许多文件(值),而我需要为每个文件夹执行的操作是汇总文件夹+所有子文件夹包含的文件数量。R:你如何总结Data.Tree中叶子和节点的数据?

示例数据:

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”,但一直未能使其工作。

这是一种有效的方法。它使用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") 
+0

谢谢,我今天会测试这两个答案。这看起来是最干净的,但有没有原因,它不是返回(sum(Get(node $ children,“Value_by_folder”))+ node $ Value)? –

+0

不,这是相同的。 R函数总是返回最后一个值。 –

+0

@EsbenEickhardt不清楚您对清洁剂的定义,但我认为这应该会更慢。你能告诉我们你的大数据集的基准测试结果吗? –

你可以这样做:

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 
+0

这是否将值保存在树中? –

+0

@EsbenEickhardt Nop。我以为你想要它作为一个更容易使用的矢量。我会更新我的答案。 –