R:修剪 data.tree 而不改变

R: Pruning data.tree without altering

data.tree 包中,当修剪一棵树时,它会永久改变这棵树。这是有问题的,因为我的 data.tree 需要很长时间才能生成,而且我不想每次都必须进行新的修剪时生成一个新的。

这里我生成一个data.tree

# Loading data and library
library(data.tree)
data(acme)

# Function to add cumulative costs to all nodes
Cost <- function(node) {
  result <- node$cost
  if(length(result) == 0) result <- sum(sapply(node$children, Cost))
  return (result)
}

# Adding costs and other data for my example
acme$Do(function(node) node$cost <- Cost(node), filterFun = isNotLeaf)
acme$IT$Outsource$AddChild("Tester Inc")
acme$IT$Outsource$`Tester Inc`$cost <- 10
print(acme, "p", "cost")
                          levelName    p    cost
1  Acme Inc.                          NA 4950000
2   ¦--Accounting                     NA 1500000
3   ¦   ¦--New Software             0.50 1000000
4   ¦   °--New Accounting Standards 0.75  500000
5   ¦--Research                       NA 2750000
6   ¦   ¦--New Product Line         0.25 2000000
7   ¦   °--New Labs                 0.90  750000
8   °--IT                             NA  700000
9       ¦--Outsource                0.20  400000
10      ¦   °--Tester Inc             NA      10
11      ¦--Go agile                 0.05  250000
12      °--Switch to R              1.00   50000

我在这里修剪树。

# Pruner function
Pruner <- function(node) {
  cost <- node$cost
  cost_parent <- node$parent$cost
  if(cost < 2800000 & cost_parent > 2800000) {
    return(TRUE)
  } else {
    return(FALSE)
  }
}

# Pruning the tree
Prune(acme, function(node) Pruner(node))
print(acme, "p", "cost")
       levelName  p    cost
1 Acme Inc.      NA 4950000
2  ¦--Accounting NA 1500000
3  ¦--Research   NA 2750000
4  °--IT         NA  700000

我曾尝试以多种方式保存我的 data.tree 对象,但它们最终都生成了巨大的文件,或者花费的时间比从头开始生成新树所花的时间更长。

# Saving object
save(acme, file = "acme.RData")
saveRDS(acme, "acme.rds")

# Generating a clone
acme_clone <- Clone(acme)

我的下一个直觉是看看我是否可以使用 Get 函数临时修剪树,因为 data.tree 文档指出 这有两种变体:临时修剪,例如仅用于打印:这是 pruneFun 参数,例如在 Get side effect or permanent pruning 中,这意味着您永久修改 data.tree 结构。这是通过 Prune 方法实现的。

由于没有示例,不清楚如何进行这项工作。

经过一番折腾,我终于尝试了以下方法,并成功运行。没有很好的例子,所以我想我会在这里留下一个。

print(acme, "cost", pruneFun = function(node) Pruner(node)) 
       levelName    cost
1 Acme Inc.      4950000
2  ¦--Accounting 1500000
3  ¦--Research   2750000
4  °--IT          700000