Nathan
Nathan

Reputation: 3648

R add a class to a field

I've created two classes in R:

library(methods)

Foo <- setClass(
    # Set the name for the class
    "Foo",

    # Define the slots
    slots = c(
              # THIS IS PROBABLY WRONG
              bar = "S4"
            ),
    )

And

Bar <- setClass(
    # Set the name for the class
    "Bar",

    # Define the slots
    slots = c(
            a = "character"
            ),

    # Set the default values for the slots. (optional)
    prototype=list(
            a = "qwerty"
            ),
    )

I want to say something along the lines of Foo.bar <- Bar(). I think that should be done something like this:

# create a method to assign the value of a coordinate
setGeneric(name="addBar",
                       def=function(theObject)
                       {
                               standardGeneric("addBar")
                       }
                       )

setMethod(f="addBar",
                      signature="Foo",
                      definition=function(theObject)
                      {
                              theObject@bar<- Bar
                      }
                      )

I then call this using:

if (!interactive()) {
    result <- tryCatch({
           foo <- Foo()
           foo <- addBar(Foo)
        }
        ,

        warning = function(war) {
            print('A warning occurred')
            print(war)
        },

        error = function(err){
            print('An error occurred')
            print(err)
        }
        )
    print(result)
}

However, if I run this I'm greeted with:

assignment of an object of class “Bar” is not valid for @‘bar’ in an object of class “Foo”; is(value, "S4") is not TRUE>

However, when I print the type of Bar, I get S4. I've tried multiple different types but I'm fresh out of ideas.

How do I assign a class object to a variable?

Upvotes: 1

Views: 1745

Answers (2)

January
January

Reputation: 17090

The class of Foo@bar should be probably Bar, and you should define the class Bar first:

Bar <- setClass("Bar",
    slots = c(a = "character"),
    prototype=list(a = "qwerty")
    )


Foo <- setClass("Foo", 
    slots = c(bar = "Bar")
    )

Please note that once you have created foo <- Foo(), the bar slot of Foo will be already initialized (try str(foo), so I think that you don't need the addBar generic. Unless it is supposed to do something else then what you describe.

Also, if anything, then you should define your method as follows:

setMethod(f="addBar", signature="Foo",
          definition=function(theObject) {
            theObject@bar<- Bar()
           })

(assuming that all you want is to initialize the @bar slot with an empty Bar() object). If you do theObject@bar <- Bar then you assign the class generator function Bar to the slot @bar and will get an error:

Error in (function (cl, name, valueClass)  : 
  assignment of an object of class “classGeneratorFunction” is not 
  valid for @‘bar’ in an object of class “Foo”; is(value, "Bar") is not TRUE

Finally, note that the call

foo <- addBar(Foo)

does not do what you think it does. Foo is a function used to generate new objects of class foo. So addBar(Foo) tries to run an addBar method on an object of class classGeneratorFunction, which is probably not what you wanted.

Upvotes: 1

Nathan
Nathan

Reputation: 3648

I changed the line

bar = "S4"

To

bar = "Bar"

This seems to solve the problem.

Upvotes: 0

Related Questions