Learn R Programming

ggraph (version 0.1.1)

treeApply: Apply a function recursively to a tree

Description

This function allows for easy recursive function calling of tree-like structures. The recursion can happen either downwards, calling the children after the parent, or upwards, calling the parent after the children. At each recursion there is access to the node(s) that was/were called before and thus have already been through the function.

Usage

treeApply(tree, FUN, ...)

# S3 method for default treeApply(tree, FUN, ...)

# S3 method for igraph treeApply(tree, FUN, direction = "down", mode = "out", ...)

# S3 method for dendrogram treeApply(tree, FUN, direction = "down", ...)

Arguments

tree
A tree-like object. Currently support for igraph objects
FUN
The function to apply to each node. The function must return a modified version of the graph if class(tree) == 'igraph' or a modified version of the node if class(tree) == 'dendrogram'
...
Additional parameters to FUN
direction
The direction of the recursion. If direction = 'down' The parent will get handled before the children, while the reverse is true if direction = 'up'
mode
For class(tree) == 'igraph' the directionality of the edges in the graph. If mode = 'out' then parents points towards their children, while the reverse is true for mode = 'in'

Value

A modified version of tree (if anything is modified in FUN)

Details

The function is called with a set of predifined parameters along with user defined ones. If direction = 'down' The parameters supplied automatically to the function are: node, parent, depth and tree, while if direction = 'up' the parameters are: node, children, depth and tree. The nature of node, parent and children depends on the class of tree. If class(tree) == 'igraph' they will be indices of the relevant vertices in the graph. If class(tree) == 'dendrogram' they will be the actual dendrogram objects.

Examples

Run this code
# We'll start with igraph
require(igraph)
gr <- graph_from_data_frame(flare$edges, vertices = flare$vertices)

# Set depth and a class based on the name of the 2nd level node name
gr <- treeApply(gr, function(node, parent, depth, tree) {
  tree <- set_vertex_attr(tree, 'depth', node, depth)
  if (depth == 1) {
    tree <- set_vertex_attr(tree, 'Class', node, V(tree)$shortName[node])
  } else if (depth > 1) {
    tree <- set_vertex_attr(tree, 'Class', node, V(tree)$Class[parent])
  }
  tree
})

# For dendrograms it's slightly different
irisDen <- as.dendrogram(hclust(dist(iris[1:4], method='euclidean'),
                         method='ward.D2'))
# Add the species information to the leafs
irisDen <- dendrapply(irisDen, function(d) {
  if(is.leaf(d))
    attr(d, 'nodePar') <- list(species=iris[as.integer(attr(d, 'label')),5])
  d
})

# Set class of node to the class of it's children they are of equal class
irisDen <- treeApply(irisDen, function(node, children, ...) {
  if (is.leaf(node)) {
    attr(node, 'Class') <- attr(node, 'nodePar')$species
  } else {
    classes <- unique(sapply(children, attr, which = 'Class'))
    if (length(classes) == 1 && !anyNA(classes)) {
      attr(node, 'Class') <- classes
    } else {
      attr(node, 'Class') <- NA
    }
  }
  node
}, direction = 'up')

Run the code above in your browser using DataLab