Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract types in R

I want to create class in R, let's say it is an S4 class for a person. E.g.

setClass("Person", slots = list(name = "character", mood = "myMoodType"))

Now I want to create myMoodType to be an abstract type that can only take the three values "Happy", "Sad" and "Unknown".

I know that I could do this using the validity for S4 classes and have the mood as a character type and check the validity by verifying that the character string provided is one of the three options I list. But I would like to know if I can define an abstract type, like in julia, e.g.

abstract myMoodType
type Happy   <: myMoodType             end
type Sad     <: myMoodType             end
type Unknown <: myMoodType             end

What would be the correct way to approach this in R?

like image 641
Gumeo Avatar asked Oct 30 '15 09:10

Gumeo


People also ask

What are the two abstract type?

There are two main types of abstract: the (1) Descriptive and the (2) Informative abstract.

Is a class an abstract type?

An abstract class is a class that is declared abstract —it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed. When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class.

What are abstract classes in programming?

Abstract class: is a restricted class that cannot be used to create objects (to access it, it must be inherited from another class). Abstract method: can only be used in an abstract class, and it does not have a body. The body is provided by the subclass (inherited from).

Which class called abstract?

A class which is declared as abstract is known as an abstract class. It can have abstract and non-abstract methods. It needs to be extended and its method implemented. It cannot be instantiated.


1 Answers

This might not be one of R's strongest and most smooth feature, but you could solve it in the following way. For more information see the documentation or the Advanced R chapter on S4.

First set up the Person class with the mood represented as a factor, and link it to a validation function that checks its levels.

check_person <- function(object) {
    if(identical(levels(object@mood), c("Happy", "Sad", "Unknown"))){
        return(TRUE)
    } else {
        return("Invalid mood.")
    }
}

setClass("Person",
         representation(name = "character", mood = "factor"),
         prototype = list(name = NA_character_,
                          mood = factor(NA, c("Happy", "Sad", "Unknown"))),
         validity = check_person)

Creating new instances with new is however a bit messy since we have to write out all the levels each time:

john <- new("Person", name="John", mood=factor("Happy", levels=c("Happy", "Sad", "Unknown")))
lucy <- new("Person", name="Lucy", mood=factor("Sad", levels=c("Happy", "Sad", "Unknown")))

Otherwise we'll get an error:

new("Person", name="Eve", mood="Unknown")
Error in validObject(.Object) : 
  invalid class “Person” object: invalid object for slot "mood" in class "Person":
  got class "character", should be or extend class "factor"

To get around that you could make your own constructor:

new_person <- function(name, mood){
    new("Person", name = name, mood = factor(mood, levels = c("Happy", "Sad", "Unknown")))
}
new_person("Eve", "Unknown")
An object of class "Person"
Slot "name":
[1] "Eve"

Slot "mood":
[1] Unknown
Levels: Happy Sad Unknown
like image 80
Backlin Avatar answered Oct 06 '22 14:10

Backlin