2011-09-19 107 views
10

我是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的遞歸節點,我認爲這是浪費資源。

我的考慮是不必要的,還是有更好的方法來做到這一點?

回答

7

這是修改後的答案。

階級聯盟很時髦 - 他們有效地插入一個類到現有的層次結構的中間,所以突然擴展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'(樹的任何一個向量,以及左右關係的一個向量)。

9

有一次,您需要使用setClassUnion("listOrNULL",members=c("list", "NULL"))來將NULL定義爲一個列表。我認爲現在是一個可用的課程。當您的設置不完整時無法測試,但定義一個超級類別的「NodeOrNull」可能會讓您過去最初的障礙。

+1

這是錢伯斯在軟件推薦的數據分析(+1) – Henrik

+0

完美的辦法,謝謝 – RockScience

+0

它完美,非常感謝 – eblondel

相關問題