【问题标题】:recursively assign unique names to nodes in a data.tree object递归地为 data.tree 对象中的节点分配唯一名称
【发布时间】:2016-02-08 20:07:09
【问题描述】:

我正在处理从 XML 块收集的列表列表,我想用 R 的 data.tree 包定义的对象来表示。下面的示例似乎有效,我可以从data.tree 列表列表的表示。但是,由于每个列表的“子”元素没有唯一标记,我无法弄清楚如何使用任何文本格式或可视化选项(例如 igraph)。

理想情况下,我想用序列号递归地重命名“儿童”。例如,转换这个:

    Children
    |-- RuleRule
    |-- RuleRule
    |-- RuleRule

到这里:

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

或者更好的是,根据诸如

之类的属性重命名“孩子”

儿童

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

这里是a similar question,这几乎就是我要找的。我不确定使用data.tree 功能是否会简化子元素的重命名,或者是否应该在初始化data.tree 对象之前完成。 data.tree 的树遍历功能似乎是正确的路线,特别是因为我将使用的数据类型可以在任何级别有多个子集。

一个独立的例子:

library(data.tree)

# 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 = structure(list(Children = NULL, RefId = "49444"), .Names = c("Children", 
"RefId")), RuleRule = structure(list(Children = NULL, RefId = "15748"), .Names = c("Children", 
"RefId")), RuleRule = structure(list(Children = NULL, RefId = "49440"), .Names = c("Children", 
"RefId")), RuleRule = structure(list(Children = NULL, RefId = "15746"), .Names = c("Children", 
"RefId")), RuleRule = structure(list(Children = NULL, RefId = "49449"), .Names = c("Children", 
"RefId"))), .Names = c("RuleRule", "RuleRule", "RuleRule", 
"RuleRule", "RuleRule", "RuleRule", "RuleRule")), Type = "product"), .Names = c("Children", 
"Type"))), .Names = "RuleOperator")), .Names = "Children")), .Names = "RuleStart")

# convert XML list into data.tree object
n <- FromListExplicit(l$RuleStart, nameName=NULL, childrenName='Children')

# check
print(n, 'RefId')

【问题讨论】:

  • data.tree 要求 name 元素至少在兄弟姐妹中是唯一的。因此,您有两种选择:要么在转换为 data.tree 结构之前使其唯一(即不使用 RuleRule 作为名称),要么使用其他名称作为名称,使用 nameName 参数。

标签: r tree


【解决方案1】:

感谢data.tree作者的建议。以下函数将递归地重命名列表的元素。它似乎有效,但欢迎使用 cmets 或更好的解决方案。

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)
      }
    }
  }

  return(l)
}

【讨论】:

    猜你喜欢
    • 2022-11-22
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多