附加到任意嵌套列表

时间:2014-11-06 16:04:50

标签: r

我有一个嵌套的列表结构,我将其用作类的基础。每个类对象可以包含另一个类对象的实例,该对象将用于链接一系列命令。我试图重载+运算符,以便能够迭代地建立一组命令。这需要找到“最深”的命令并附加到它。这是我没有运气的地方。

# an aribitrarily nested list
tmp <- list(x = list(x = list(x = list())))

# find deepest 'x'
last.x <- function(e) {
  while(!is.null(e$x)){
    e <- e$x
  }
  return(e)
}

# I need to be able to append to the deepest 'x' in the list. Ideally:
last.x(tmp)$x <- list()

产生错误:

Error in last.x(tmp)[["x"]] <- list() : 
  could not find function "last.x<-"

我正在寻找的是通过引用访问“最深”x并将孩子附加到其中的某种方式。

2 个答案:

答案 0 :(得分:4)

如果从R中的数据结构中提取某些值然后更改提取的对象,则不会影响原始数据结构(也就是说,提取的对象不会像指向原始数据的指针那样)。例如,考虑从虹膜数据集中复制物种,然后更改提取的值:

species <- iris$Species
species[1] <- "virginica"
species[1]
# [1] virginica
# Levels: setosa versicolor virginica
iris$Species[1]
# [1] setosa
# Levels: setosa versicolor virginica

但是,您仍然可以通过构建一个新的嵌套列表来完成您想要做的事情,并在最低级别添加子级。这是使用递归函数执行此操作的方法:

tmp
# $x
# $x$x
# $x$x$x
# list()

rec <- function(x) {
  if (is.null(x$x))  return(list(x=list()))
  else  return(list(x=rec(x$x)))
}
rec(tmp)
# $x
# $x$x
# $x$x$x
# $x$x$x$x
# list()

答案 1 :(得分:1)

提供我的解决方案,希望它对其他人有用。感谢josilber提供灵感。在尝试创建一个简单示例时,我排除了一些难以直接应用答案的细节。

从三个对象开始,每个对象都是深度列表1:

obj1 <- structure(list(), class='obj')
obj2 <- structure(list(), class='obj')
obj3 <- structure(list(), class='obj')

自定义添加功能,可以将后续对象更深一层:

`+.obj` <- function(e1, e2) {  
  if (is.null(e1$x)) {
    e1$x <- e2
  } else {
    e1$x <- e1$x + e2
  }
  return(e1)  
}

示例输出

res <- obj1 + obj2 + obj3

> str(res)
List of 1
 $ x:List of 1
  ..$ x: list()
  .. ..- attr(*, "class")= chr "obj"
  ..- attr(*, "class")= chr "obj"
 - attr(*, "class")= chr "obj"