Node: Create a 'data.tree' Structure With 'Nodes'

Description Usage Format Details Active bindings Methods See Also Examples

Description

Node is at the very heart of the data.tree package. All trees are constructed by tying together Node objects.

Usage

1
# n1 <- Node$new("Node 1")

Format

An R6Class generator object

Details

Assemble Node objects into a data.tree structure and use the traversal methods to set, get, and perform operations on it. Typically, you construct larger tree structures by converting from data.frame, list, or other formats.

Most methods (e.g. node$Sort()) also have a functional form (e.g. Sort(node))

Active bindings

name

Gets or sets the name of a Node. For example Node$name <- "Acme".

parent

Gets or sets the parent Node of a Node. Only set this if you know what you are doing, as you might mess up the tree structure!

children

Gets or sets the children list of a Node. Only set this if you know what you are doing, as you might mess up the tree structure!

isLeaf

Returns TRUE if the Node is a leaf, FALSE otherwise

isRoot

Returns TRUE if the Node is the root, FALSE otherwise

count

Returns the number of children of a Node

totalCount

Returns the total number of Nodes in the tree

path

Returns a vector of mode character containing the names of the Nodes in the path from the root to this Node

pathString

Returns a string representing the path to this Node, separated by backslash

position

The position of a Node within its siblings

fields

Will be deprecated, use attributes instead

fieldsAll

Will be deprecated, use attributesAll instead

attributes

The attributes defined on this specific node

attributesAll

The distinct union of attributes defined on all the nodes in the tree spanned by this Node

levelName

Returns the name of the Node, preceded by level times '*'. Useful for printing and not typically called by package users.

leaves

Returns a list containing all the leaf Nodes

leafCount

Returns the number of leaves are below a Node

level

Returns an integer representing the level of a Node. For example, the root has level 1.

height

Returns max(level) of any of the Nodes of the tree

isBinary

Returns TRUE if all Nodes in the tree (except the leaves) have count = 2

root

Returns the root of a Node in a tree.

siblings

Returns a list containing all the siblings of this Node

averageBranchingFactor

Returns the average number of crotches below this Node

Methods

Public methods


Method new()

Create a new Node object. This is often used to create the root of a tree when creating a tree programmatically.

Usage
Node$new(name, check = c("check", "no-warn", "no-check"), ...)
Arguments
name

the name of the node to be created

check

Either

  • "check": if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)

  • "no-warn": if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)

  • "no-check" or FALSE: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors

...

A name-value mapping of node attributes

Returns

A new 'Node' object

Examples
node <- Node$new("mynode", x = 2, y = "value of y")
node$y


Method AddChild()

Creates a Node and adds it as the last sibling as a child to the Node on which this is called.

Usage
Node$AddChild(name, check = c("check", "no-warn", "no-check"), ...)
Arguments
name

the name of the node to be created

check

Either

  • "check": if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)

  • "no-warn": if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)

  • "no-check" or FALSE: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors

...

A name-value mapping of node attributes

Returns

The new Node (invisibly)

Examples
root <- Node$new("myroot", myname = "I'm the root")
root$AddChild("child1", myname = "I'm the favorite child")
child2 <- root$AddChild("child2", myname = "I'm just another child")
child3 <- child2$AddChild("child3", myname = "Grandson of a root!")
print(root, "myname")


Method AddChildNode()

Adds a Node as a child to this node.

Usage
Node$AddChildNode(child)
Arguments
child

The child "Node" to add.

Returns

the child node added (this lets you chain calls)

Examples
root <- Node$new("myroot")
child <- Node$new("mychild")
root$AddChildNode(child)


Method AddSibling()

Creates a new Node called name and adds it after this Node as a sibling.

Usage
Node$AddSibling(name, check = c("check", "no-warn", "no-check"), ...)
Arguments
name

the name of the node to be created

check

Either

  • "check": if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)

  • "no-warn": if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)

  • "no-check" or FALSE: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors

...

A name-value mapping of node attributes

Returns

the sibling node (this lets you chain calls)

Examples
#' root <- Node$new("myroot")
child <- root$AddChild("child1")
sibling <- child$AddSibling("sibling1")


Method AddSiblingNode()

Adds a Node after this Node, as a sibling.

Usage
Node$AddSiblingNode(sibling)
Arguments
sibling

The "Node" to add as a sibling.

Returns

the added sibling node (this lets you chain calls, as in the examples)

Examples
root <- Node$new("myroot")
child <- Node$new("mychild")
sibling <- Node$new("sibling")
root$AddChildNode(child)$AddSiblingNode(sibling)


Method RemoveChild()

Remove the child Node called name from a Node and returns it.

Usage
Node$RemoveChild(name)
Arguments
name

the name of the node to be created

Returns

the subtree spanned by the removed child.

Examples
node <- Node$new("myroot")$AddChild("mychild")$root
node$RemoveChild("mychild")


Method RemoveAttribute()

Removes attribute called name from this Node.

Usage
Node$RemoveAttribute(name, stopIfNotAvailable = TRUE)
Arguments
name

the name of the node to be created

stopIfNotAvailable

Gives an error if stopIfNotAvailable and the attribute does not exist.

Examples
node <- Node$new("mynode")
node$RemoveAttribute("age", stopIfNotAvailable = FALSE)
node$age <- 27
node$RemoveAttribute("age")
node


Method Sort()

Sort children of a Node or an entire data.tree structure

Usage
Node$Sort(attribute, ..., decreasing = FALSE, recursive = TRUE)
Arguments
attribute

determines what is collected. The attribute can be

  • a.) the name of a field or a property/active of each Node in the tree, e.g. acme$Get("p") or acme$Get("position")

  • b.) the name of a method of each Node in the tree, e.g. acme$Get("levelZeroBased"), where e.g. acme$levelZeroBased <- function() acme$level - 1

  • c.) a function, whose first argument must be a Node e.g. acme$Get(function(node) node$cost * node$p)

...

any parameters to be passed on the the attribute (in case it's a method or a function)

decreasing

sort order

recursive

if TRUE, the method will be called recursively on the Node's children. This allows sorting an entire tree.

Details

You can sort with respect to any argument of the tree. But note that sorting has side-effects, meaning that you modify the underlying, original data.tree object structure.

See also Sort for the equivalent function.

Returns

Returns the node on which Sort is called, invisibly. This can be useful to chain Node methods.

Examples
data(acme)
acme$Do(function(x) x$totalCost <- Aggregate(x, "cost", sum), traversal = "post-order")
Sort(acme, "totalCost", decreasing = FALSE)
print(acme, "totalCost")


Method Revert()

Reverts the sort order of a Node's children.

See also Revert for the equivalent function.

Usage
Node$Revert(recursive = TRUE)
Arguments
recursive

if TRUE, the method will be called recursively on the Node's children. This allows sorting an entire tree.

Returns

returns the Node invisibly (for chaining)


Method Prune()

Prunes a tree.

Pruning refers to removing entire subtrees. This function has side-effects, it modifies your data.tree structure!

See also Prune for the equivalent function.

Usage
Node$Prune(pruneFun)
Arguments
pruneFun

allows providing a a prune criteria, i.e. a function taking a Node as an input, and returning TRUE or FALSE. If the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.

Returns

the number of nodes removed

Examples
data(acme)
acme$Do(function(x) x$cost <- Aggregate(x, "cost", sum))
Prune(acme, function(x) x$cost > 700000)
print(acme, "cost")


Method Climb()

Climb a tree from parent to children, by provided criteria.

Usage
Node$Climb(...)
Arguments
...

an attribute-value pairlist to be searched. For brevity, you can also provide a character vector to search for names.

node

The root Node of the tree or subtree to climb

Details

This method lets you climb the tree, from crutch to crutch. On each Node, the Climb finds the first child having attribute value equal to the the provided argument.

See also Climb and Navigate

Climb(node, ...)

Returns

the Node having path ..., or NULL if such a path does not exist

Examples
data(acme)

#the following are all equivalent
Climb(acme, 'IT', 'Outsource')
Climb(acme, name = 'IT', name = 'Outsource')
Climb(acme, 'IT')$Climb('Outsource')
Navigate(acme, path = "IT/Outsource")

Climb(acme, name = 'IT')

Climb(acme, position = c(2, 1))
#or, equivalent:
Climb(acme, position = 2, position = 1)
Climb(acme, name = "IT", cost = 250000)

tree <- CreateRegularTree(5, 2)
tree$Climb(c("1", "1"), position = c(2, 2))$path



Method Navigate()

Navigate to another node by relative path.

Usage
Node$Navigate(path)
Arguments
path

A string or a character vector describing the path to navigate

node

The starting Node to navigate

Details

The path is always relative to the Node. Navigation to the parent is defined by .., whereas navigation to a child is defined via the child's name. If path is provided as a string, then the navigation steps are separated by '/'.

See also Navigate and Climb

Examples
data(acme)
Navigate(acme$Research, "../IT/Outsource")
Navigate(acme$Research, c("..", "IT", "Outsource"))


Method Get()

Traverse a Tree and Collect Values

Usage
Node$Get(
  attribute,
  ...,
  traversal = c("pre-order", "post-order", "in-order", "level", "ancestor"),
  pruneFun = NULL,
  filterFun = NULL,
  format = FALSE,
  inheritFromAncestors = FALSE,
  simplify = c(TRUE, FALSE, "array", "regular")
)
Arguments
attribute

determines what is collected. The attribute can be

  • a.) the name of a field or a property/active of each Node in the tree, e.g. acme$Get("p") or acme$Get("position")

  • b.) the name of a method of each Node in the tree, e.g. acme$Get("levelZeroBased"), where e.g. acme$levelZeroBased <- function() acme$level - 1

  • c.) a function, whose first argument must be a Node e.g. acme$Get(function(node) node$cost * node$p)

...

in case the attribute is a function or a method, the ellipsis is passed to it as additional arguments.

traversal

defines the traversal order to be used. This can be

pre-order

Go to first child, then to its first child, etc.

post-order

Go to the first branch's leaf, then to its siblings, and work your way back to the root

in-order

Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling

level

Collect root, then level 2, then level 3, etc.

ancestor

Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the pruneFun

function

You can also provide a function, whose sole parameter is a Node object. The function is expected to return the node's next node, a list of the node's next nodes, or NULL.

Read the data.tree vignette for a detailed explanation of these traversal orders.

pruneFun

allows providing a prune criteria, i.e. a function taking a Node as an input, and returning TRUE or FALSE. If the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.

filterFun

allows providing a a filter, i.e. a function taking a Node as an input, and returning TRUE or FALSE. Note that if filter returns FALSE, then the node will be excluded from the result (but not the entire subtree).

format

if FALSE (the default), no formatting is being used. If TRUE, then the first formatter (if any) found along the ancestor path is being used for formatting (see SetFormat). If format is a function, then the collected value is passed to that function, and the result is returned.

inheritFromAncestors

if TRUE, then the path above a Node is searched to get the attribute in case it is NULL.

simplify

same as sapply, i.e. TRUE, FALSE or "array". Additionally, you can specify "regular" if each returned value is of length > 1, and equally named. See below for an example.

Details

The Get method is one of the most important ones of the data.tree package. It lets you traverse a tree and collect values along the way. Alternatively, you can call a method or a function on each Node.

See also Get, Node, Set, Do, Traverse

Returns

a vector containing the atrributes collected during traversal, in traversal order. NULL is converted to NA, such that length(Node$Get) == Node$totalCount

Examples
data(acme)
acme$Get("level")
acme$Get("totalCount")
 

acme$Get(function(node) node$cost * node$p,
         filterFun = isLeaf)

#This is equivalent:
nodes <- Traverse(acme, filterFun = isLeaf)
Get(nodes, function(node) node$cost * node$p)

   
#simplify = "regular" will preserve names
acme$Get(function(x) c(position = x$position, level = x$level), simplify = "regular")
 

Method Do()

Executes a function on a set of nodes

Usage
Node$Do(
  fun,
  ...,
  traversal = c("pre-order", "post-order", "in-order", "level", "ancestor"),
  pruneFun = NULL,
  filterFun = NULL
)
Arguments
fun

the function to execute. The function is expected to be either a Method, or to take a Node as its first argument

...

A name-value mapping of node attributes

traversal

defines the traversal order to be used. This can be

pre-order

Go to first child, then to its first child, etc.

post-order

Go to the first branch's leaf, then to its siblings, and work your way back to the root

in-order

Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling

level

Collect root, then level 2, then level 3, etc.

ancestor

Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the pruneFun

function

You can also provide a function, whose sole parameter is a Node object. The function is expected to return the node's next node, a list of the node's next nodes, or NULL.

Read the data.tree vignette for a detailed explanation of these traversal orders.

pruneFun

allows providing a prune criteria, i.e. a function taking a Node as an input, and returning TRUE or FALSE. If the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.

filterFun

allows providing a a filter, i.e. a function taking a Node as an input, and returning TRUE or FALSE. Note that if filter returns FALSE, then the node will be excluded from the result (but not the entire subtree).

Details

See also Node, Get, Set, Traverse

Examples
data(acme)
acme$Do(function(node) node$expectedCost <- node$p * node$cost)
print(acme, "expectedCost")


Method Set()

Traverse a Tree and Assign Values

Usage
Node$Set(
  ...,
  traversal = c("pre-order", "post-order", "in-order", "level", "ancestor"),
  pruneFun = NULL,
  filterFun = NULL
)
Arguments
...

each argument can be a vector of values to be assigned. Recycled.

traversal

defines the traversal order to be used. This can be

pre-order

Go to first child, then to its first child, etc.

post-order

Go to the first branch's leaf, then to its siblings, and work your way back to the root

in-order

Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling

level

Collect root, then level 2, then level 3, etc.

ancestor

Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the pruneFun

function

You can also provide a function, whose sole parameter is a Node object. The function is expected to return the node's next node, a list of the node's next nodes, or NULL.

Read the data.tree vignette for a detailed explanation of these traversal orders.

pruneFun

allows providing a prune criteria, i.e. a function taking a Node as an input, and returning TRUE or FALSE. If the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.

filterFun

allows providing a a filter, i.e. a function taking a Node as an input, and returning TRUE or FALSE. Note that if filter returns FALSE, then the node will be excluded from the result (but not the entire subtree).

Details

The method takes one or more vectors as an argument. It traverses the tree, whereby the values are picked from the vector. Also available as OO-style method on Node.

See also Node, Get, Do, Traverse

Returns

invisibly returns the nodes (useful for chaining)

Examples
data(acme)
acme$Set(departmentId = 1:acme$totalCount, openingHours = NULL, traversal = "post-order")
acme$Set(head = c("Jack Brown", 
                  "Mona Moneyhead", 
                  "Dr. Frank N. Stein", 
                  "Eric Nerdahl"
                  ),
         filterFun = function(x) !x$isLeaf
        )
print(acme, "departmentId", "head")
 

Method clone()

The objects of this class are cloneable with this method.

Usage
Node$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

See Also

For more details see the data.tree documentations, or the data.tree vignette: vignette("data.tree")

Node

Sort

Examples

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
library(data.tree)
acme <- Node$new("Acme Inc.")
accounting <- acme$AddChild("Accounting")$
              AddSibling("Research")$
              AddChild("New Labs")$
              parent$
              AddSibling("IT")$
              AddChild("Outsource")
print(acme)



## ------------------------------------------------
## Method `Node$new`
## ------------------------------------------------

node <- Node$new("mynode", x = 2, y = "value of y")
node$y


## ------------------------------------------------
## Method `Node$AddChild`
## ------------------------------------------------

root <- Node$new("myroot", myname = "I'm the root")
root$AddChild("child1", myname = "I'm the favorite child")
child2 <- root$AddChild("child2", myname = "I'm just another child")
child3 <- child2$AddChild("child3", myname = "Grandson of a root!")
print(root, "myname")


## ------------------------------------------------
## Method `Node$AddChildNode`
## ------------------------------------------------

root <- Node$new("myroot")
child <- Node$new("mychild")
root$AddChildNode(child)


## ------------------------------------------------
## Method `Node$AddSibling`
## ------------------------------------------------

#' root <- Node$new("myroot")
child <- root$AddChild("child1")
sibling <- child$AddSibling("sibling1")


## ------------------------------------------------
## Method `Node$AddSiblingNode`
## ------------------------------------------------

root <- Node$new("myroot")
child <- Node$new("mychild")
sibling <- Node$new("sibling")
root$AddChildNode(child)$AddSiblingNode(sibling)


## ------------------------------------------------
## Method `Node$RemoveChild`
## ------------------------------------------------

node <- Node$new("myroot")$AddChild("mychild")$root
node$RemoveChild("mychild")


## ------------------------------------------------
## Method `Node$RemoveAttribute`
## ------------------------------------------------

node <- Node$new("mynode")
node$RemoveAttribute("age", stopIfNotAvailable = FALSE)
node$age <- 27
node$RemoveAttribute("age")
node


## ------------------------------------------------
## Method `Node$Sort`
## ------------------------------------------------

data(acme)
acme$Do(function(x) x$totalCost <- Aggregate(x, "cost", sum), traversal = "post-order")
Sort(acme, "totalCost", decreasing = FALSE)
print(acme, "totalCost")


## ------------------------------------------------
## Method `Node$Prune`
## ------------------------------------------------

data(acme)
acme$Do(function(x) x$cost <- Aggregate(x, "cost", sum))
Prune(acme, function(x) x$cost > 700000)
print(acme, "cost")


## ------------------------------------------------
## Method `Node$Climb`
## ------------------------------------------------

data(acme)

#the following are all equivalent
Climb(acme, 'IT', 'Outsource')
Climb(acme, name = 'IT', name = 'Outsource')
Climb(acme, 'IT')$Climb('Outsource')
Navigate(acme, path = "IT/Outsource")

Climb(acme, name = 'IT')

Climb(acme, position = c(2, 1))
#or, equivalent:
Climb(acme, position = 2, position = 1)
Climb(acme, name = "IT", cost = 250000)

tree <- CreateRegularTree(5, 2)
tree$Climb(c("1", "1"), position = c(2, 2))$path



## ------------------------------------------------
## Method `Node$Navigate`
## ------------------------------------------------

data(acme)
Navigate(acme$Research, "../IT/Outsource")
Navigate(acme$Research, c("..", "IT", "Outsource"))


## ------------------------------------------------
## Method `Node$Get`
## ------------------------------------------------

data(acme)
acme$Get("level")
acme$Get("totalCount")
 

acme$Get(function(node) node$cost * node$p,
         filterFun = isLeaf)

#This is equivalent:
nodes <- Traverse(acme, filterFun = isLeaf)
Get(nodes, function(node) node$cost * node$p)

   
#simplify = "regular" will preserve names
acme$Get(function(x) c(position = x$position, level = x$level), simplify = "regular")
 

## ------------------------------------------------
## Method `Node$Do`
## ------------------------------------------------

data(acme)
acme$Do(function(node) node$expectedCost <- node$p * node$cost)
print(acme, "expectedCost")


## ------------------------------------------------
## Method `Node$Set`
## ------------------------------------------------

data(acme)
acme$Set(departmentId = 1:acme$totalCount, openingHours = NULL, traversal = "post-order")
acme$Set(head = c("Jack Brown", 
                  "Mona Moneyhead", 
                  "Dr. Frank N. Stein", 
                  "Eric Nerdahl"
                  ),
         filterFun = function(x) !x$isLeaf
        )
print(acme, "departmentId", "head")
 

Example output

                       levelName
1 Acme Inc.                     
2  <U+00A6>--Accounting         
3  <U+00A6>--Research           
4  <U+00A6>   <U+00B0>--New Labs
5  <U+00B0>--IT                 
6      <U+00B0>--Outsource      
[1] "value of y"
              levelName                 myname
1 myroot                          I'm the root
2  <U+00A6>--child1     I'm the favorite child
3  <U+00B0>--child2     I'm just another child
4      <U+00B0>--child3    Grandson of a root!
  levelName
1   mychild
[1] FALSE
[1] TRUE
  levelName
1    mynode
                                        levelName totalCost
1  Acme Inc.                                        4950000
2   <U+00A6>--IT                                     700000
3   <U+00A6>   <U+00A6>--Switch to R                  50000
4   <U+00A6>   <U+00A6>--Go agile                    250000
5   <U+00A6>   <U+00B0>--Outsource                   400000
6   <U+00A6>--Accounting                            1500000
7   <U+00A6>   <U+00A6>--New Accounting Standards    500000
8   <U+00A6>   <U+00B0>--New Software               1000000
9   <U+00B0>--Research                              2750000
10      <U+00A6>--New Labs                           750000
11      <U+00B0>--New Product Line                  2000000
[1] 5
                           levelName    cost
1 Acme Inc.                          4950000
2  <U+00A6>--Accounting              1500000
3  <U+00A6>   <U+00B0>--New Software 1000000
4  <U+00B0>--Research                2750000
5      <U+00A6>--New Product Line    2000000
6      <U+00B0>--New Labs             750000
  levelName
1 Outsource
  levelName
1 Outsource
  levelName
1 Outsource
  levelName
1 Outsource
               levelName
1 IT                    
2  <U+00A6>--Outsource  
3  <U+00A6>--Go agile   
4  <U+00B0>--Switch to R
         levelName
1 New Product Line
         levelName
1 New Product Line
  levelName
1  Go agile
NULL
  levelName
1 Outsource
  levelName
1 Outsource
               Acme Inc.               Accounting             New Software 
                       1                        2                        3 
New Accounting Standards                 Research         New Product Line 
                       3                        2                        3 
                New Labs                       IT                Outsource 
                       3                        2                        3 
                Go agile              Switch to R 
                       3                        3 
               Acme Inc.               Accounting             New Software 
                      11                        3                        1 
New Accounting Standards                 Research         New Product Line 
                       1                        3                        1 
                New Labs                       IT                Outsource 
                       1                        4                        1 
                Go agile              Switch to R 
                       1                        1 
            New Software New Accounting Standards         New Product Line 
                  500000                   375000                   500000 
                New Labs                Outsource                 Go agile 
                  675000                    80000                    12500 
             Switch to R 
                   50000 
            New Software New Accounting Standards         New Product Line 
                  500000                   375000                   500000 
                New Labs                Outsource                 Go agile 
                  675000                    80000                    12500 
             Switch to R 
                   50000 
         Acme Inc. Accounting New Software New Accounting Standards Research
position         1          1            1                        2        2
level            1          2            3                        3        2
         New Product Line New Labs IT Outsource Go agile Switch to R
position                1        2  3         1        2           3
level                   3        3  2         3        3           3
                                        levelName expectedCost
1  Acme Inc.                                                NA
2   <U+00A6>--Accounting                                    NA
3   <U+00A6>   <U+00A6>--New Software                   500000
4   <U+00A6>   <U+00B0>--New Accounting Standards       375000
5   <U+00A6>--Research                                      NA
6   <U+00A6>   <U+00A6>--New Product Line               500000
7   <U+00A6>   <U+00B0>--New Labs                       675000
8   <U+00B0>--IT                                            NA
9       <U+00A6>--Outsource                              80000
10      <U+00A6>--Go agile                               12500
11      <U+00B0>--Switch to R                            50000
                                        levelName departmentId
1  Acme Inc.                                                11
2   <U+00A6>--Accounting                                     3
3   <U+00A6>   <U+00A6>--New Software                        1
4   <U+00A6>   <U+00B0>--New Accounting Standards            2
5   <U+00A6>--Research                                       6
6   <U+00A6>   <U+00A6>--New Product Line                    4
7   <U+00A6>   <U+00B0>--New Labs                            5
8   <U+00B0>--IT                                            10
9       <U+00A6>--Outsource                                  7
10      <U+00A6>--Go agile                                   8
11      <U+00B0>--Switch to R                                9
                 head
1          Jack Brown
2      Mona Moneyhead
3                    
4                    
5  Dr. Frank N. Stein
6                    
7                    
8        Eric Nerdahl
9                    
10                   
11                   

data.tree documentation built on Aug. 3, 2020, 5:12 p.m.