2017-09-08 5 views
4

나는 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"함수를 사용하려고했지만 작동하지 못했습니다.

답변

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

감사합니다. 오늘 두 가지 답변을 시험해 보겠습니다. 이것은 가장 깨끗한 것처럼 보입니다. 그러나 반환되지 않는 이유가 있습니다 (sum (Get (node ​​$ children, "Value_by_folder")) + node $ Value)? –

+0

아니요, 동일합니다. R 함수는 항상 마지막 값을 반환합니다. –

+0

@EsbenEickhardt 청소기의 정의에 대해 잘 모르겠지만 이것은 느려야합니다. 더 큰 데이터 세트의 벤치마킹 결과를 알려주시겠습니까? –

1

당신은 할 수 있습니다 : R의 게으른 평가는 res을 채우기 위해 원하는 순서로 망쳐 놨 때문에

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가 중요하다.

은 당신이 얻을 :

> 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. 나는 당신이 그것을 사용하기 쉬운 벡터로 원한다고 생각했다. 내 대답을 업데이트 할게. –