R Data Structure 4: Classes
Note: This is the final R Data Structure post, after this, we go into Flask (Python), and Shiny (R) on how you can build your own custom dashboards.
If you know how to program in Python, and understand the concept of classes, and objects quite well, then this is the R equivalent to it. An R object refers to a data structure with attributes, and methods which act on those attributes. A class is a blueprint of an object. Think about a class as like a blueprint, it describes the basic buildings blocks that the object will contain.
Then, afterwards something can constructed from those blueprints. When you build something from those blueprints, you are essentially building an object (instance of a class), and the process of making an object from a class is called “instantiation”.
In R, we have 2 different types of classes:
S3
S4
1 - S3 Class
S3 classes are a system for object-oriented programming. S3 provides a simple mechanism to create classes and methods without extensive formal definitions. S3 is built around the use of generic functions and method dispatch based on the class attribute of objects.
1.1 Defining an S3 Class
An S3 class is defined primarily by creating a constructor function that assigns a class attribute to an object. This involves taking a base type of R object—like a list or a vector—and adding a class attribute to it. Here's a simple example of defining an S3 class for a "Person" object:
Person <- function(name, age) {
# Creating a list and assigning class attribute 'Person'
object <- list(name = name, age = age)
class(object) <- "Person"
return(object)
}
This code snippet defines a new S3 class called Person, which stores a name and an age
1.2 Creating Objects from a class
Using the constructor function Person defined above, you can easily create new instances of the Person class:
# Creating a new Person object
john <- Person("John Doe", 30)
The object john
now is an instance of the S3 class Person and has properties name and age as defined.
1.3 Methods
Methods in S3 are functions that perform operations specifically for objects of a certain class. These methods are defined by creating functions with a specific naming convention: the generic function name followed by a dot and the class name. For example, if you want to define a print method for the Person class, you would do the following:
print.Person <- function(x) {
cat("Person Name:", x$name, "\nAge:", x$age, "\n")
}
With this method defined, when you call print(john), R goes to the print.Person() function automatically:
print(john)
# Output:
# Person Name: John Doe
# Age: 30
2 - S4 Class
S4 classes in R provide a formal approach to object-oriented programming. They were introduced in order to address some of the limitations and ambiguities of S3. S4 supports explicit class definitions, formal inheritance, and method dispatch based on multiple arguments. Ideally, S4 classes come in handy for handling large scale software solutions
2.1 S4 vs S3 Classes
S4 differs significantly from S3 in several key areas:
Formal Class Definitions: S4 requires explicit class definitions using the setClass() function, which includes specifying the properties (slots) and their classes.
Strong Typing: Each slot in an S4 class has a defined class, and only objects of that class or its subclasses can be assigned to the slot.
Multiple Dispatch: S4 can dispatch methods based on the class of multiple arguments, whereas S3 typically dispatches based only on the class of the first argument.
Validation: S4 allows for formal validation of objects upon creation or modification, ensuring that objects are always in a valid state.
2.2 Defining S4 Classes
Defining an S4 class involves specifying its properties, and their data types. Here’s how to define an S4 class for a Person:
setClass("Person",
slots = list(
name = "character",
age = "numeric"
))
This definition creates a new S4 class named Person with two slots: name, which must be a character vector, and age, which must be numeric.
2.3 Modifying Properties (slots)
In S4, slots are accessed and modified using the @ operator or the slot() function. Here's how you can create an object of the Person class and modify its slots:
# Creating an object of the Person class
john <- new("Person", name = "John Doe", age = 30)
# Modifying slots
john@age <- 31 # Directly accessing the slot
# Alternatively using the slot function
slot(john, "name") <- "Johnny Doe"
2.4 Methods
Methods in S4 are defined using setMethod(). The method definition specifies the generic function it applies to, the classes of the objects it handles, and the method itself. Here’s an example of defining a print method for the Person class:
setMethod("show",
"Person",
function(object) {
cat("Person Name:", object@name, "\nAge:", object@age, "\n")
})
This show method overrides the default print behavior for objects of the Person class, providing a custom display format. When you print a Person object, R uses this method to display the object:
print(john)
# Output:
# Person Name: Johnny Doe
# Age: 31
And, with that, we’re wrapping up R data structures, and going straight to either Flask, or Dash (Python).