如何在R中将槽的默认值设置为NULL?

问题描述:

我是R新手。如何在R中将槽的默认值设置为NULL?

我想定义一个类似于树节点的类,也就是说,它有一个左节点和右节点,它应该与父节点具有相同的类。所以我定义的类,如下所示:

setClass('Node', representation=(left='Node',right='Node', ...)) 

我想设置节点的默认值是通过设置一个原型NULL,但[R表示如下:

invalid class "Node" object: invalid object for slot "left" in class "bicluster": got class "NULL", should be or extend class "Node" 

但如果我不”默认值为NULL,那么默认值将是一个深度为4的递归节点,我认为这是浪费资源。

我的考虑是不必要的,还是有更好的方法来做到这一点?

这是修改后的答案。

阶级联盟很时髦 - 他们有效地插入一个类到现有的层次结构的中间,所以突然扩展list的东西现在扩展listOrNULL

相反,我会创建一个小类代表“树”,可以是“空”或“内部”的层次结构。 “内部”类将有一个插槽来包含数据(类型为“ANY”),以及左侧和右侧链接,它们将是“树”元素。

setClass("Tree") 

setClass("Empty", contains="Tree") 

setClass("Internal", contains="Tree", 
     representation=representation(elem="ANY", left="Tree", right="Tree"), 
     prototype=prototype(left=new("Empty"), right=new("Empty"))) 

我会写一个构造我的树,创建一个空树的方法,并从一个元素树加左,右的后裔。

setGeneric("Tree", function(elem, left, right) standardGeneric("Tree"), 
      signature="elem") 

setMethod(Tree, "missing", function(elem, left, right) new("Empty")) 

setMethod(Tree, "ANY", function(elem, left, right) { 
    new("Internal", elem=elem, left=left, right=right) 
}) 

的基本操作是将一个元件x插入到树t

setGeneric("insert", function(x, t) standardGeneric("insert")) 

setMethod(insert, c("ANY", "Empty"), function(x, t) { 
    Tree(x, Tree(), Tree()) 
}) 

setMethod(insert, c("ANY", "Internal"), function(x, t) { 
    if (x < [email protected]) { 
     l <- insert(x, [email protected]) 
     r <- [email protected] 
    } else { 
     l <- [email protected] 
     r <- insert(x, [email protected]) 
    } 
    Tree([email protected], l, r) 
}) 

另一操作是测试籍

setGeneric("member", function(x, t) standardGeneric("member")) 

setMethod(member, c("ANY", "Empty"), function(x, t) FALSE) 

setMethod(member, c("ANY", "Internal"), function(x, t) { 
    if (x < [email protected]) member(x, [email protected]) 
    else if ([email protected] < x) member(x, [email protected]) 
    else TRUE 
}) 

这个实现的一个有趣的,功能性的,属性是它是持久的

> t <- Tree() 
> t1 <- insert(10, t) 
> t2 <- insert(5, t1) 
> t3 <- insert(7, t2) 
> t4 <- insert(15, t3) 
> which(sapply(1:20, member, t4)) 
[1] 5 7 10 15 
> which(sapply(1:20, member, t2)) 
[1] 5 10 

由于S4类创建效率低下以及修改树(例如,添加节点)将路径中的所有节点复制到新节点,因此当有大量更新时,这不会很有效。 A different approach将该树表示为左值,右值三元组的matrix。 S4的实现仍然会有糟糕的表现,因为实例的更新会创建新的实例,复制所有内容。所以我最终会参考一个参考类,其中包含字段'value'(树的任何一个向量,以及左右关系的一个向量)。

有一次,您需要使用setClassUnion("listOrNULL",members=c("list", "NULL"))来将NULL定义为一个列表。我认为现在是一个可用的课程。当您的设置不完整时无法测试,但定义一个超级类别的“NodeOrNull”可能会让您过去最初的障碍。

+1

这是钱伯斯在软件推荐的数据分析(+1) – Henrik

+0

完美的办法,谢谢 – RockScience

+0

它完美,非常感谢 – eblondel