2011-09-19 9 views
10

私はRを初めて使いましたスロットのデフォルト値をRに設定するには?

私はツリーノードに似たクラスを定義しようとしています。つまり、それは左ノードと右ノードを持ちます。これは親ノードと同じクラスでなければなりません。次のようにだから私は、クラスを定義します。

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になります。

代わりに、「空」または「内部」のいずれかの「ツリー」を表す小さなクラス階層を作成します。 "Internal"クラスには、( "ANY"タイプの)データと "Tree"要素である左右のリンクを含むスロットがあります。

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) 
}) 

基本的な動作は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 
}) 

のために、この実施の興味深い、機能、プロパティをテストすることであるツリーに要素xを挿入することですそれが永続的であるということです。

> 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クラスの作成が非効率であることや、ツリーを変更する(ノードを追加するなど)、パス内のすべてのノードが新しいノードにコピーされるため、多くの更新がある場合は効率的ではありません。 different approachは、ツリーを左、右、値の三つ組のmatrixとして表します。インスタンスの更新によって新しいインスタンスが作成され、すべてが複製されるため、S4実装のパフォーマンスは低下します。だから私はフィールド '値'(ツリーが保持するはずのベクトルと左と右の関係のmatrix)を持つ参照クラスで終わるだろう。

9

一度は、リストとして定義されたスロットにNULLを取得するために、setClassUnion("listOrNULL",members=c("list", "NULL"))を使用する必要がありました。私は今それが利用可能なクラスだと思います。あなたのセットアップが不完全な間はテストできませんが、スーパークラスの "NodeOrNull"を定義すると、あなたの最初の障壁を越えてしまいます。

+1

これは、データ分析のためのソフトウェアでチェンバースが推奨するアプローチ(1) – Henrik

+0

完璧です、おかげで – RockScience

+0

それは完璧に動作し、 – eblondel

関連する問題