[This article was first published on Tag: r – Appsilon | Enterprise R Shiny Dashboards, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)


Want to share your content on R-bloggers? click here if you have a blog, or here if you don’t.

Object-oriented programming (OOP) is a popular and widely embraced programming paradigm in software development. The concept of object-oriented programming in R has been previously featured in one of our blog posts, specifically within the context of R6 classes.

In this blog post, we will dive deeper into the world of object-oriented programming, understand why it’s a valuable approach worthy of adoption, and its implementation in R.

Table of Contents


What Was the Motivation Behind Introducing OOP in R?

The R Foundation describes R as a language and environment for statistical computing and graphics. It originated from the S language and environment, which was developed at Bell Laboratories.

The days of the S language is where we will start our tour on the history of OOP in R. S allowed users to use different kinds of statistical models. Even though statistical models can be different, they share a common set of operations, such as printing, making predictions, plotting, or updating the model.

Uniform functions were introduced to make it easier for users to interact with those models. Good examples of such uniform functions are print(), predict(), plot(), update(). These functions can be invoked on any model, irrespective of whether it’s a linear regression model or a time series model like ARIMA (Autoregressive Integrated Moving Average) working under the hood.

Interested in elevating your coding with Functional Programming in R? Check out our introductory article; ‘Unlocking the Power of Functional Programming in R.

Why Do Developers Need OOP?

A uniform interface simplifies interactions for users of code that employs OOP principles, but what drives our choice to utilize OOP in our own code?

Let’s go back to the example of having different models and the uniform print function. Without using OOP, we might implement this function as:

print <- function(x) {
  if (inherits(x, "lm")) {
    # print linear model
  } else if (inherits(x, "Arima")) {
    # print arima model
  }
}

While this might not look that bad, imagine how long that function would be if it supported printing every available model in R.

Another issue with this approach is that only the author of the function can add new types there. This reduces flexibility as developers who would want print to support their own classes, would need to reach out to the author of the print function.

Object-oriented programming allows us to have a separate implementation of the print function for each of our classes. Some of you might recognize that this example is similar to how it would look written in the S3 OOP; we will be diving deeper into S3 in subsequent posts.

print <- function(x, ...) {
  # Generic function
}

print.lm <- function(x, ...) {
  # print linear model
}

print.Arima <- function(x, ...) {
  # print arima model
}

 

Much better! Our code is now:

  1. More modular – instead of one big function, we have multiple smaller functions, which improves readability and can make testing easier.
  2. Flexible – Potentially, other users can now add their own print functions without having to modify any existing ones.

This section was inspired by Hadley Wickham’s talk: An Introduction to R7.

What is OOP?

Now, we have an idea of why we might want to use object-oriented programming, but have not yet defined what it is:

Object-oriented programming is a programming paradigm where we identify the following principles: Encapsulation, Polymorphism, Abstraction, and Inheritance.

In the article, we already had a chance to see encapsulation, polymorphism, and abstraction in action:

  • Polymorphism allows us to perform the same action in different ways (call the print function but call it on different models).
  • Encapsulation allows us to not worry about the internal details of the object when interacting with the object (e.g. how coefficients are stored in our linear model).
  • Abstraction allows us to not worry about the internal implementation details of the object (for example, what method is used for fitting the linear regression).

We will explore inheritance in more detail when diving into specific OOP systems in R, but for completeness:

  • Inheritance – classes can reuse code from other classes by designing relationships (hierarchy) between them. For example, in R, the glm class inherits from the lm class

Additionally, there are a couple of terms that are often used when talking about OOP (We already used some of them!)

  • Classes – user-defined data types that serve as blueprints for creating objects; they define what fields or data an instance of the class contains (for example, an instance of the lm class has a coefficients field which contains a named vector of coefficients)
  • Objects – instances of individual classes; for example, each linear regression model is a linear regression model, but they can differ from each other (for example, they can be trained on different data)
  • Methods – a function associated with a given class; they describe what an object can do. For example, you can make predictions using a linear regression model.

OOP Systems in R

All right, so how do we do OOP in R? Turns out R provides different ways of doing OOP:

  1. S3
  2. S4
  3. Reference Classes (referred to as RC or sometimes R5)
  4. R6

Interested in experiencing R6 Classes in action while designing a video game in R Shiny? Check out our article, How to Build a Video Game in R Shiny with CSS, JavaScript, and R6 Classes.

On top of that, there is a new OOP being developed called S7 (previously also called R7), and there are also other packages R packages providing ways of doing OOP in R including:

  1. proto
  2. R.oo

Some packages also defined their own OOP systems; for example, torch defined its own OOP system called R7 (not to be confused with R7 developed by the R Consortium, which is now called S7).

Each of those has its own advantages and disadvantages that we will be exploring in subsequent articles, so stay tuned.

Conclusion

The first appearance of OOP in R comes from the S language. Object-oriented programming was used in S to provide a common set of functions for interacting with statistical models. OOP makes it easy to provide end users with a uniform interface to a family of different classes (e.g. different statistical models).

OOP provides developers with flexibility and allows their code to be more modular. There are multiple ways of doing OOP in R, and more are being developed. We’ll dive deeper into object-oriented programming in R; stay tuned for our next article in this series.

Have questions about Object-Oriented Programming (OOP) in R or need support with your enterprise R/Shiny project? Feel free to reach out to us for assistance!

The post appeared first on appsilon.com/blog/.

To leave a comment for the author, please follow the link and comment on their blog: Tag: r – Appsilon | Enterprise R Shiny Dashboards.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you’re looking to post or find an R/data-science job.


Want to share your content on R-bloggers? click here if you have a blog, or here if you don’t.

Continue reading: Object-Oriented Programming in R (Part 1): An Introduction

Understanding and Embracing Object-Oriented Programming in R

The object-oriented programming (OOP) paradigm has become a cornerstone in modern software development practices. Its implementation in R bolsters the language’s capabilities and versatility, providing both developers and end-users with a myriad of benefits.

The Rationale for Introducing OOP in R

Based on S language from Bell Laboratories, R enhances statistical computing and graphics but needed a way to simplify interactions with different types of statistical models such as linear regression or time series, like ARIMA. The introduction of OOP with uniform functions like print(), plot(), or predict() enabled easy interaction with these models irrespective of their underlying specifics.

Benefits to Developers

OOP lets developers break down large functions into smaller, more manageable parts, thereby improving readability and ease of testing. It also offers flexibility as it allows other users to add their own print functions without having to modify the existing ones. Code becomes more modular and extensible, thereby enhancing coding practices and software quality.

Key Concepts of OOP

Object-oriented programming touts four fundamental principles: Encapsulation, Polymorphism, Abstraction, and Inheritance.

  1. Polymorphism: It enables us to perform the same action in different ways, i.e., call the print function on different models.
  2. Encapsulation: It allows for the concealment of the object’s internal details when interacting with it, promoting software robustness.
  3. Abstraction: It reduces complexity by allowing us to overlook the internal implementation details of an object.
  4. Inheritance: It facilitates code reuse through the hierarchy of classes, with one class utilizing properties of another.

We use classes to define the properties of an object, methods to describe what an object can do, and objects are individual instances of classes.

OOP Systems in R

R provides diverse ways of implementing OOP, including:

  • S3
  • S4
  • Reference Classes, also known as RC or sometimes R5.
  • R6
  • New OOP being developed called S7 (previously also called R7).
  • The proto and R.oo packages.

Each method has its unique advantages and disadvantages, making it crucial to understand each system better before deciding to use it. A clear understanding of these systems leads to better programming practices and improved project outcomes.

Wrapping Up

The emergence of OOP in R originated from the S language and has greatly enhanced the versatility and capacity of R for statistical computing. It has simplified the interface for users and afforded developers more flexibility in their code. As more OOP systems are developed within R, a deep understanding and appreciation of these systems becomes increasingly essential for maximising the utility of the R programming language.

Advice

When implementing OOP in R, choose the OOP system that best fits your specific needs and project requirements. Aim for modular and flexible code that is easy to read, debug, and maintain. Always keep abreast of developments in OOP systems within R to ensure you are making full use of the evolving capabilities of this versatile language.

Read the original article