R Tutorial
Fundamentals of R
Variables
Input and Output
Decision Making
Control Flow
Functions
Strings
Vectors
Lists
Arrays
Matrices
Factors
DataFrames
Object Oriented Programming
Error Handling
File Handling
Packages in R
Data Interfaces
Data Visualization
Statistics
Machine Learning with R
In R, the S3 system is a simple and flexible way to create object-oriented structures. S3 is the older and simpler object system in R, compared to the more formal S4 system. It's based on conventions rather than strict rules, making it relatively straightforward but less strict than S4.
Let's dive into a basic tutorial of S3 classes in R:
To create an S3 object, you essentially just assign a class to a standard R object using the class()
function:
my_obj <- 1:10 class(my_obj) <- "my_class"
One of the cornerstones of the S3 system is the idea of generic functions and method dispatch. A generic function is a function that has methods for different classes of objects.
A generic function is a function that dispatches methods based on the class of its arguments. Here's a simple generic function:
my_generic <- function(x, ...) { UseMethod("my_generic") }
To create an S3 method for our class, we follow the naming convention [generic].[class]
:
my_generic.my_class <- function(x) { cat("This is a method for", class(x), "class.\n") }
Now when we call my_generic(my_obj)
, it will dispatch to my_generic.my_class
:
my_generic(my_obj) # Output: This is a method for my_class class.
S3 classes support simple inheritance. When a method for a class isn't found, R will then look for methods of the parent class:
# Adding a parent class class(my_obj) <- c("my_class", "my_parent_class") # Creating a method for the parent class my_generic.my_parent_class <- function(x) { cat("This is a method for", class(x)[2], "class.\n") } my_generic(my_obj) # Output: This is a method for my_class class.
Even though my_obj
has a my_parent_class
class, R still uses the my_class
method because it's the most specific. If we didn't have a method for my_class
, it would use the method for my_parent_class
.
You often want to create utility functions to help with S3 class construction or extraction of components:
# Constructor make_my_class <- function(x) { out <- x class(out) <- "my_class" return(out) } # Extractor get_data.my_class <- function(x) { unclass(x) }
Advantages:
Limitations:
The S3 system in R offers a flexible way to create object-oriented structures. While it lacks the formality and robustness of the S4 system, its simplicity can be an advantage, especially for simpler tasks. As with any tool, choosing to use S3 should be based on the specific needs of your project.
Defining S3 classes in R:
# Example of defining an S3 class setClass("Person", slots = c(name = "character", age = "numeric"))
Methods and generics in S3 classes:
# Example of defining a generic function for an S3 class setGeneric("getInfo", function(object) standardGeneric("getInfo"))
S3 class inheritance in R:
# Example of S3 class inheritance setClass("Employee", contains = "Person", slots = c(salary = "numeric"))
Creating and using S3 objects in R:
# Example of creating and using S3 objects person <- new("Person", name = "John Doe", age = 30)
S3 dispatch in R:
# Example of S3 dispatch getInfo.Person <- function(object) { paste("Name:", object@name, "Age:", object@age) } getInfo(person)
Advantages of S3 classes over other systems in R:
Advantages: - Simplicity and flexibility - Lightweight and easy to understand - No formal definition of classes required
Examples of S3 class usage in R:
# Example of using S3 classes for geometric shapes setClass("Shape", slots = c(color = "character")) circle <- new("Shape", color = "red")
How to implement S3 methods in R:
# Example of implementing an S3 method getInfo.Shape <- function(object) { paste("Color:", object@color) }
S3 classes vs S4 classes in R:
S3 Classes: - Informal and flexible - Lightweight - Single dispatch S4 Classes: - Formal and structured - Rich features, e.g., multiple dispatch - Strict definition requirements
Debugging S3 class methods in R:
# Example of debugging an S3 method debug(getInfo.Shape) getInfo(circle)