knitr::opts_chunk$set( warning = FALSE, message = FALSE, echo = TRUE, comment = "#>" )
Built on the top of data.tree, a Node (tree) is an R6 object that is especially useful when we are facing hierarchical data. The forestry package helps to reshape or create tree objects. Since data.tree has the capability to convert a tree to JSON using toJSON()
after converting to a list using as.list()
, the forestry package is particularly useful when creating a specific JSON object for building htmlwidgets. The forestry package aims to reshape or create tree objects with a specific format.
create_nodes()
creates a Node object. tree_name
is to assign the name of this Node. add_children_count
is to assign the number of children to this Node, it will be listed in numerical order. To assign values to each node, simply put the appropriate variable as a parameter with a vector containing the values. The name of the parameter will be the variable name and the values in the vector will be assigned to each node respectively.
library(data.tree) library(forestry) new_node <- create_nodes(tree_name = "tree1", add_children_count = 3, class = c("A", "B", "C") ) print(new_node, "class")
The fill_NA_level()
function will fill missing values across the desired level with desired value (default as 0).
For example, new_node
is a tree with missing value in hc field.
new_node <- create_nodes(tree_name = "tree1", add_children_count = 3, hc = c(1, 2, NA)) print(new_node, "hc" )
We apply fill_NA_level()
to new_node
, simply put new_node
as input_node
, assign the field_name
with hc
, and assign by_level = 2
, we will fill the NA
in hc field with 0 across level 2.
result <- fill_NA_level(input_node = new_node, field_name = "hc", by_level = 2, fill_with = 0) print(result, "hc")
create_tree()
creates a new tree from a list. It appends each item of the input list as a numbered child in the new tree. This is useful when we convert a Node to a JSON array.
For instance, let's use test_node$children
(a list) as an example. We can see a list of groupA, groupB and groupC.
data(test_df) test_node <- data.tree::as.Node(test_df) print(test_node$children)
Now we see that this list is reshaped into a list, new_tree, with each item in test_node$children
added as a child. The index of each item in the list is assigned as the name of each child.
library(data.tree) test_node <- as.Node(test_df) new_shape <- create_tree(test_node$children,"new_tree") print(new_shape, "hc")
fix_items()
creates a tree with fixed children nodes from another tree. It automatically copies fields to the tree and fills missing values with NA
. Similar to left joining to a tree with certian children nodes.
This function is to make sure the tree has the desired children nodes.
See cell_node2, it has only B and C.
cell_node2 <- Node$new("cell2") cell_node2$AddChild("B") cell_node2$AddChild("C") cell_node2$Set(class = c(NA, "B1", "C1")) print(cell_node2, "class")
Now we put fix_vector = c("A", "B", "C", "D")
and assign to a new tree, cell_fixed_items
. We can see that cell_fixed_items
has all of the nodes from fix_vector
and still inherits the fields from cell_node2
.
cell_fixed_items <- fix_items(fix_vector = c("A", "B", "C", "D"), input_node = cell_node2) print(cell_fixed_items, "class")
children_sort()
function sorts the children nodes into a desired order. If there are children nodes not listed in the input_order
, we can set the mismatch_last
parameter (default is T
) to put the mismatched children nodes to the top or bottom.
data(test_df) test_node <- data.tree::as.Node(test_df) sorted_node <- children_sort( input_node = test_node, input_order = c("groupB", "groupA"), mismatch_last = T) print(sorted_node)
cumsum_across_level()
gets the cummulative value across a level, the cummulative value will be added to the cumsum_number
field.
In this example, it calculates the cummulative exercise_time
field across level 3.
data(exercise_df) exercise_node <- as.Node(exercise_df) test <- forestry::cumsum_across_level(input_node = exercise_node, attri_name = "exercise_time", level_num = 3) print(test, "cumsum_number", "exercise_time", "level")
In addition, level_num = "All"
will get the cummumative value across all levels. Please note that there should be no missing values in the appropriate level when we apply cumsum_across_level()
.
data(exercise_df) exercise_node <- as.Node(exercise_df) exercise_node$Do(function(node) node$exercise_time <- Aggregate(node, attribute = "exercise_time", aggFun = sum), traversal = "post-order") print(exercise_node, "exercise_time") exercise_node_test <- cumsum_across_level(input_node = exercise_node, attri_name = "exercise_time", level_num = "All") print(exercise_node_test,"exercise_time", "cumsum_number", "level")
The pre_get_array()
function changes the numeric item name in a list into a format that is compatible with the JSON array standard. As mentioned earlier, when converting a tree to JSON, we need to save the tree as a list using as.list()
then use htmlwidgets:::toJSON()
to convert the list to JSON data.
For example, new_node
is a tree with numeric children nodes.
new_node <- create_nodes(tree_name = "tree1", add_children_count = 3, class = c("A", "B", "C")) print(as.list(new_node) )
We can see the numeric children node names are listed. If we apply pre_get_array()
to this list, we can change all numeric names so the nodes can be saved as a JSON array instead of JSON objects after we use htmlwidgets:::toJSON()
.
new_node <- create_nodes(tree_name = "tree1", add_children_count = 3, class = c("A", "B", "C")) print(pre_get_array(as.list(new_node) ) )
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.