我有一个嵌套的列表结构,我将其用作类的基础。每个类对象可以包含另一个类对象的实例,该对象将用于链接一系列命令。我试图重载+
运算符,以便能够迭代地建立一组命令。这需要找到“最深”的命令并附加到它。这是我没有运气的地方。
# 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并将孩子附加到其中的某种方式。
答案 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"