问题描述
考虑一个递归构造的任意深度嵌套的 S4 对象:
setClass("person",representation(name = "character",child = "ANY"),prototype(name = "",child = NA_real_))
createGeneology <- function(children){
object <- new("person",name = children[1])
if(length(children) > 1) object@child <- createGeneology(children[2:length(children)])
return(object)
}
object <- createGeneology(children = c("Arthur","Aiden","Adalyn","Ava","Aaron","Andy"))
在现实世界中,每一层中的槽对下面的层有一定的依赖性。在这种情况下,它只是一个静态的家谱。
我可以通过输入路径直接访问和修改插槽:
differentKid <- new("person",name = "Logan")
genIV <- object@child@child@child
object@child@child@child <- differentKid
如何动态完成(无需输入任意数量的 @child
元素?)
我可以通过构造一个字符串并使用 parse
对其进行评估来动态访问该对象,但是此技巧不适用于将对象修改为 {{ 1}} 尝试将结果解析为数组:
eval
str <- "object@child@child@child"
genIV <- eval(parse(text = str))
不起作用:
do.call
do.call("<-",list(eval(parse(text = str)),"new('Person',name = 'Logan')"))
不起作用,assign
不起作用,所以这只是不好的做法,有没有更好的方法来做到这一点,或者我遗漏了什么?
我在 Stack Overflow 上看到过类似的问题,但他们没有处理 S4 对象(它们的处理方式与列表和数组略有不同)。
解决方法
还是很高兴听到有人有想法。与此同时,我一直无法找到一种方法来动态访问和修改 S4 对象中的深层递归层。相反,最好的解决方案是递归地将对象折叠成一个层列表。
由于在特定于类的 as.list
操作中折叠层的内存开销,我决定在强制执行连续层之间的关系的同时查找对象列表。