Search code examples
rr-s4

How can I set up a Class containing itself in R (for a tree)?


I need a class that may or may not contain itself, for usage as a tree in R. Every Node has Side, Analytical_Matrix, MaxChi2 and P and Sons are of type Node too.

The first time a Node is created, I need the Sons to be empty or NULL. But later I create them and asign them as Sons (I have a limit of max 3 sons).

I have tried this for setting up the Class:

setClass(Class = "Node",slots=c(Side="character",Analytical_matrix="data.frame",MaxChi2="data.frame",P="numeric",TerminalNode="logical",LSon="Node",CSon="Node",RSon="Node"),prototype = prototype(LSon=NULL,CSon=NULL,RSon=NULL))

And this for declaring one instance of the new class. I get an error. I need the sons to be empty first because is an infinite loop looking always for Sons of Sons of Sons.

Res=new(Class = "Node",Side=c("A","B"),Analytical_Matrix=data.frame(A=c(1,2)),MaxChi2=data.frame(A=c(3)),P=0.3),NodoTerminal=FALSE)

Solution

  • It is possible to have a class contain itself as one of its slots, via a "class union". Here is a simple example of a class with an id integer slot and a parent slot that we want to be the same class:

    setClass("myObject",representation(
        parent="myObject_or_NULL",
        id="integer"
    ),prototype=prototype(
        parent=NULL
    )) -> myObject
    
    setClassUnion("myObject_or_NULL",c("myObject","NULL"))
    

    The above will generate a warning that "myObject_or_NULL" isn't defined, but it's only a warning and not an error.

    Now, if we try to make a new one:

    myObject()
    
    An object of class "myObject"
    Slot "parent":
    NULL
    
    Slot "id":
    integer(0)
    

    We don't have a recursive loop any more because the default is NULL. After it's instantiated, you can set the slot to whatever you like, of course.