Home Ask Login Register

Developers Planet

Your answer is one click away!

Dylan February 2016

recursively assign unique names to nodes in a data.tree object

I am working with a list of lists, collected from an XML chunk, that I would like to represent with object defined by the data.tree package for R. The example below seems to work, and I can extract elements from the data.tree representation of the list of lists. However, I cannot figure out how to use any of the text-formatting or visualization options (e.g. igraph) due to the fact that "child" elements of each list are not uniquely labeled.

Ideally, I would like to recursively re-name "Children" with a serial number. For example, convert this:

    |-- RuleRule
    |-- RuleRule
    |-- RuleRule

To this:

    |-- RuleRule_01
    |-- RuleRule_02
    |-- RuleRule_03

Or even better, re-name the "Children" according to an attribute such as


    |-- RuleRule_15976
    |-- RuleRule_49444
    |-- RuleRule_15748

Here is a similar question that is almost what I am looking for. I am not sure if the use of data.tree functionality would simplify the re-naming of children elements, or if this should be done before initializing the data.tree object. The tree-traversal capabilities of data.tree seem like the right route, especially since the types of data I will be using can have multiple set of children, at any level.

A self-contained example:


# a typical list
l <- structure(list(RuleStart = structure(list(Children = structure(list(
RuleOperator = structure(list(Children = structure(list(RuleRule = structure(list(
    Children = NULL, RefId = "49446"), .Names = c("Children", 
"RefId")), RuleRule = structure(list(Children = NULL, RefId = "15976"), .Names = c("Children", 
"RefId")), RuleRule = structur        


Dylan February 2016

Thanks to the author of data.tree for the suggestion. The following function will recursively re-name elements of a list. It seems to work, but comments or a better solution are welcome.

makeNamesUnique <- function(l) {
  l.names <- names(l$Children)
  # multiple children types
  tab <- table(l.names)
  t.names <- names(tab)

  # iterate over types
  for(this.type in seq_along(t.names)) {
    # iterate over duplicate names
    # get an index to this type
    idx <- which(l.names == t.names[this.type])
    for(this.element in seq_along(idx)) {
      # make a copy of this chunk of the tree
      l.sub <- l$Children[[idx[this.element]]]
      # if this is a terminal leaf then re-name and continue
      if(is.null(l.sub$Children)) {
        # print('leaf')
        names(l$Children)[idx[this.element]] <- paste0(t.names[this.type], '_', this.element)
      # otherwise re-name and then step into this element and apply this function recursively
      else {
        # print('branch')
        names(l$Children)[idx[this.element]] <- paste0(t.names[this.type], '_', this.element)
        # fix this branch and splice back into tree
        l$Children[[idx[this.element]]] <- makeNamesUnique(l.sub)


Post Status

Asked in February 2016
Viewed 2,632 times
Voted 11
Answered 1 times


Leave an answer

Quote of the day: live life