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

Polymorphism in R

Polymorphism, in the context of object-oriented programming, is the ability of different classes to be treated as instances of the same class through inheritance. In R, polymorphism is mainly seen through its S3 and S4 object systems. R isn't traditionally thought of as an object-oriented language like Java or C++, but it does offer mechanisms to achieve polymorphism.

This tutorial will discuss polymorphism in R using the S3 system, which is simpler and more commonly used than the S4 system.

1. Understanding Basic S3 Classes and Methods

In the S3 system, the class of an object is simply a string attribute.

# Create a simple S3 object
person <- list(name="Alice", age=30)
class(person) <- "Person"

To create methods that act polymorphically on the object, you use the UseMethod function. For instance, let's create a generic print method for our Person class:

print.Person <- function(x, ...) {
  cat("Person\n")
  cat("Name:", x$name, "\n")
  cat("Age:", x$age, "\n")
}

print(person)

2. Polymorphism in Action

To see polymorphism in action, we'll create another class and implement a method for it:

student <- list(name="Bob", age=20, major="Biology")
class(student) <- "Student"

print.Student <- function(x, ...) {
  cat("Student\n")
  cat("Name:", x$name, "\n")
  cat("Age:", x$age, "\n")
  cat("Major:", x$major, "\n")
}

print(student)

If we create a generic method that can accept both Person and Student objects, the correct method is dispatched based on the class:

describe <- function(x) {
  UseMethod("describe", x)
}

describe.Person <- function(x) {
  cat("This is a person named", x$name, "who is", x$age, "years old.\n")
}

describe.Student <- function(x) {
  cat("This is a student named", x$name, "who is studying", x$major, "and is", x$age, "years old.\n")
}

describe(person)
describe(student)

This is polymorphism: The same function name (describe) behaves differently depending on the class of the object it's given.

3. Inheritance and Polymorphism

S3 classes also allow for a simple form of inheritance:

# Extend the Person class
class(student) <- c("Student", "Person")

If a method isn't found for the Student class, R will then look for a method for the Person class. This behavior allows you to create default methods for base classes.

4. Conclusion

R's S3 system offers a flexible and lightweight approach to object-oriented programming. While it lacks some of the strictness and structure of other languages' object-oriented systems, it's well-suited to R's data analysis focus. If you need more complex object-oriented features, you can look into the S4 system or the newer R6 system.

  1. S4 classes and methods for polymorphism in R:

    • Overview: Explore S4 classes and methods as a mechanism for implementing polymorphism in R.

    • Code:

      # S4 class definition
      setClass("Shape", slots = c(length = "numeric"))
      
      # Method for area calculation
      setGeneric("calculateArea", function(object) standardGeneric("calculateArea"))
      setMethod("calculateArea", "Shape", function(object) {
        cat("Calculating area of a generic shape\n")
        return(object@length ^ 2)
      })
      
      # Create instances of the Shape class
      square <- new("Shape", length = 5)
      rectangle <- new("Shape", length = 4)
      
      # Polymorphic method invocation
      calculateArea(square)
      calculateArea(rectangle)
      
  2. Using polymorphic behavior in R programming:

    • Overview: Showcase how polymorphic behavior allows functions to work with different types of objects.

    • Code:

      # Using polymorphic behavior in R programming
      calculateArea(square)
      calculateArea(rectangle)
      
  3. Implementing polymorphic functions in R:

    • Overview: Demonstrate how to create polymorphic functions that can handle different types of inputs.

    • Code:

      # Implementing polymorphic functions in R
      calculateArea <- function(object) {
        cat("Calculating area of a generic shape\n")
        return(object@length ^ 2)
      }
      
      # Polymorphic function invocation
      calculateArea(square)
      calculateArea(rectangle)