Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5

R Object Oriented Programming
#1

I had started an R Introduction thread in the Algorithmic Trading with R forum. Later on I decided to start an additional forum on R as a programming language. R is a statistical analysis language that was started by two professors in New Zealand in 1993 to teach statistics courses. Over the years it has developed tremendously. Today there are more than 10K R libraries. If you want to do statistical analysis you will find the R library that will do the work for you. In this thread I want to discuss R Object Oriented Programming (OOP) that makes R a general purpose language. 

R uses objects a lot. If you are familiar with OOP that objects are just instances of classes that have been defined. Everything that we use in R is an object based on some S3 class. When R got developed it had a class structure that is known as S3. Most R buildin classes are S3 classes. S3 classes are basically lists. I will define S3 class in a moment. R provides you with polymorphism, encapsulation and inheritance just like any other modern Object Oriented Programming language. In addition to S3 classes we also have now S4 classes which were added after a number of years to add safety to its structure.

Polymorphism means you can use the same function on different classes without much problem. The inbuilt class methods take care of how the function is applied. Inheritance means that we can use a class and derive a new class based on that class that inherits its methods. Inheritance allows you to extend a class to a more specialized class that has the methods of the parent class as well as its own methods.

For example I give you an example FRBS is an R library that does fuzzy logic. But it does only fuzzy type 1 logic. I have not found an R library that does fuzzy type 2 interval logic. So this is what we can do. We can use inheritance and build a fuzzy type 2 interval logic based on FRBS fuzzy type 1 logic. I will do that here but first let's master R object oriented programming.

Subscribe My YouTube Channel:
https://www.youtube.com/channel/UCUE7VPo...F_BCoxFXIw

Join Our Million Dollar Trading Challenge:
https://www.doubledoji.com/million-dolla...challenge/
Reply
#2

S3 Classes

R has three type of classes structures, S3, S4 and R5. S3 class structure is the simplest to learn, use and understand. S3 class structure is an informal class structure that allows you to define methods and functions on objects. Everything is an object in R you should know this. So vectors, lists, matrices, dataframes etc all are objects. Informal structure of S3 is also its limitations. S3 has no formal structure to ensure that objects meet the requirements for the class.

In Object Oriented Programming (OPP) we define classes. Classes are blueprints or templates that we use to define objects. Classes have attributes based on variables and features and methods that operate on those attributes and modify them. For example we can define a Car class with variables and features and methods like stop, accelerate, turn, park etc. Mercedes car that you drive will be an object of this Car class. Using the methods stop, accelerate, turn, park, you can drive your Mercedes car object.

All objects in R can be treated as vectors. Based on this basic object R has inbuilt objects like lists which are generic vectors, dataframes which comprises of lists. The only condition is that these lists should be of equal length. Matrices and arrays are also vector with an additional attribute that indicates its dimension. This is important for you to know. S3 classes are created based on these inbuilt objects and classes that are provided in R base package. So S3 classes are custom classes that are created using regular R objects like lists, matrices, vectors, dataframes, arrays. Most of the inbuilt R classes are of S3 type.

Let's create our Car class using S3 structure.

Cars <- function(number_plate = "XYNZZZZ",
                        electric = FALSE,
                        kilometers = 0,
                        model_year = "2018" ) {

me <- structure(list( number_plate= number_plate,
                              electric= electric,
                              kilometers = kilometers,
                              model_year = model_year ),
                              class= "Cars")
                               return(me) }

Above is the basic template for the Cars S3 class. In this template when we define a car object we provide the number plate, we specify whether we have an electric car or a petrol/diesel car, we also provide the kilometers run by the car as well as the model year of the car. So first we define the Cars as a function with default values.  Next we make a reference to the function in parentheses using me variable which gets returned as the class Cars object. I added the attribute electric as electric cars are getting popular all over the world as compared to petrol/diesel cars. Now this is just a rudimentary class declaration for educational purposes. You can make it more elaborate by adding more variables. Now you can cleary see above S3 class structure is a list.

Subscribe My YouTube Channel:
https://www.youtube.com/channel/UCUE7VPo...F_BCoxFXIw

Join Our Million Dollar Trading Challenge:
https://www.doubledoji.com/million-dolla...challenge/
Reply
#3

In the last post we discussed how to make S3 classes. I made a simple Cars class. As you saw it was a list that was converted into a class. First we defined a function. Then we made a list of the function parameters and then used the return variables me to tell R to treat the function as S3 class.  Let define on object based on the Mercedes car that you drive daily:

mercedes1 <- Cars(number_plate = "BM725WT",
                            electric=FALSE,
                             kilometers = 500,
                            model_year = "15/01/2018")

S3 Methods

As you can see, we have defined an mercedes1 object as I want to leave the possibility to define more mercedes cars. We could have included the car company in the definition of our Car class. I didn't do it. You can do it if you want. The number plate is BM725WT. Since the car is petrol, I have made electric parameter FALSE. Since the car was bought in January of this years, you only drove it for 500 KM. Now this variable will change with the passage of time. Let's define a method that will help us to change the kilometers driven by our car. We will be using UseMethod to define a generic function that we can use anytime to change the kilometers driven reading.

set_kilometers<- function(entity,value_to_set) {
                         UseMethod("set_kilometers",entity) }

set_kilometers.default <- function(entity,value_to_set)
                         { return(NULL) }

set_kilometers.Cars <- function(entity,value_to_set) {
                       entity$kilometers <- value_to_set message("Kilometers reading was correctly set")
                       return(entity) }

Now that we have define the method that we can use to change the kilometers driven reading, let's change the kilometers to 1500 KM.

mercedes1 <- set_kilometers(mercedes1, 1500)

Now you can easily check that the kilometers driven by our mercedes are indeeed 1500 KM with the following R command:

mercedes1$kilometers

This was a simple example on how to create S3 classes and then define methods on that class to modify its behavior. But as said above S3 is an informal method that lacks the true power of modern object oriented programming. This problem is resolved with the introduction of S4 classes in R. S3 classes is based on default R objects. S3 methods are generic functions that are defined to change the class object parameters. Keep this in mind S3 classes are easy to define and operate upon as shown by the simple example above. In the next post we are going to discuss S4 classes.

Subscribe My YouTube Channel:
https://www.youtube.com/channel/UCUE7VPo...F_BCoxFXIw

Join Our Million Dollar Trading Challenge:
https://www.doubledoji.com/million-dolla...challenge/
Reply
#4

S3 objects do not behave like objects in Java, C++, Python.  S3 objects are quite simple objects that we can use in many cases with ease however. S3 class object is used to dictate a function how it will respond when the class list is passed to it. In this post we discuss S4 classes. Just keep in mind S3 are informal classes while S4 is a formal class.

S4 Classes

When defining S4 classes we first define the class and data formally and after that we class methods separately. Let's make this clear by defining a Bee S4 Class. Just keep this in mind bees are flying insects. The most popular bee is the honey bee. We all love to eat honey that is produced by these bees. Honey bees live in colonies. So let's start. First step is to define the Bee S4 class. We can define S4 classes using setClass command:

# Define the Bee class.

Bee <- setClass (


# declare the name of the class
"Bee",


# define the data types (slots) that the class will track
slots = c(

# size of the bee which can be in mm.
bee_size="numeric",     

# the position of the bees. This is a (x,y,z) vector. Beehive has position (0,0,0). With this vector we measure
#the bee distance from it's hive
bee_position="numeric",


# Probability that bee will transition from flying to not flying.

pFlying="numeric",

# Probability that bee will transition from not flying to flying.

pNotFlying="numeric",

# The bee's current activity level.


currentActivity="numeric"


),

# Set the default values for the slots. This is optional
prototype=list( bee_size=10.0,
                      bee_position=c(0.0,0.0,0.0), #bee is in the beehive this is the default position
                      pFlying=0.0,                        #since the bee is in the beehive it's not flying
                      pNotFlying=1.0,
                      currentActivity=0.5
),

# Now make a function that will test if the data is consistent.
# This is optional but always a helpful step

validity=function(object)
{
# First check if the currentActivity and the bee_size is a non-negative number
if(object@currentActivity<0.0) {
              return("Error: Current activity is negative which is not possible")
} else if (object@bee_size<0.0) {
             return("Error: Bee size cannot be negative")
}
             return(TRUE)
}
)

Subscribe My YouTube Channel:
https://www.youtube.com/channel/UCUE7VPo...F_BCoxFXIw

Join Our Million Dollar Trading Challenge:
https://www.doubledoji.com/million-dolla...challenge/
Reply
#5

In the last post we used the setClass command to create the Bee class. A class has two things in it. Data and methods. We use the methods to modify class data. We used the setClass command to declare the Bee class data. We did not define any method. So in S4 class we first define the class data. Once we have that then we can define the methods that we can use on the class data. Bee class has bee size, bee position plus the probability whether it is flying and the probability that it is not flying and the bee current activity level.

So when we declare any bee object we will need this data. We also provided the default values for the data so that if no data is provided, R will use the default data. After that we define the validity function. This is optional but a good practice to define such a validity function. This function checks if the data values provided make sense or not. For example bee size cannot be negative. Bee activity level also cannot be negative. So once we initialize a new Bee object with data this function will automatically check the data values and give an error if the data values are not consistent. In case of error, object will not be created. Defining a bee is now easy.

bee1 <- new("Bee")

Since we haven't provided any values, this object will have default values. We can also provide default values:

bee2 <- new ("Bee", bee_size=12, bee_position=c(100,200,300))

Since we haven't provided probability of flying and not flying plus the currentActivity, these will have default values.  

S4 Methods

We used setClass command to create an S4 class. We will now define methods on that class that we can use to modify the class data. Methods in S4 are almost similar to the methods in S3. There is no concept of public and private methods in R. We have make this distinction on our own level as programmers.

Subscribe My YouTube Channel:
https://www.youtube.com/channel/UCUE7VPo...F_BCoxFXIw

Join Our Million Dollar Trading Challenge:
https://www.doubledoji.com/million-dolla...challenge/
Reply
#6

When defining S4 methods, you cannot use the names reserved for default methods like print, show etc. When we define a new method on S4 classes, we first tell R about it using setGeneric command. So let's define a method that can get the bee size. First we use the setGeneric command to inform R about a new method getSize

setGeneric(name <- "getSize",
def <- function(bees)
{
standardGeneric("getSize")
}
)

Now we use the setMethod to get the size of bee object in the Bee S4 class.

setMethod(f <- "getSize",
signature <-"Bee",
definition <- function(bees)
{
return(bees@bee_size)
}
)

Now that we have define the getSize method we can use to get the size of bee object.

bee4 <- new("Bee", bee_size=15)
getSize(bee4)

This was the getSize method that will be used anytime we want to get the size of bee. Now let's define setSize method that will modify the bee size. In this case first we will make a copy of the bee size before we modify it. First we use the setGeneric command to tell R about the new method setSize.

setGeneric(name <-"setSize",
def<-function(bees,newSize)
{
standardGeneric("setSize")
}
)

Now we formally define the new method.

setMethod(f<-"setSize",
signature<-"Bee",
definition<-function(bees,newSize)
{
if(newSize>0.0) {
bees@bee_size <- newSize
} else {
warning("Error - invalid bee size passed");
}
return(bees)
}
)

Now we have defined a new method setSize that can modify the size of bee.

bee5 <- new("Bee", bee_size=10)

Check the bee size

bee5@bee_size

Modify bee size with a new bee size

bee5 <- setSize(bee5, 15)

Check the new bee size:

bee5@bee_size

Did you notice the difference? In S3 classes when we want to access any S3 class object data we use the $ like in meredes1$kilometers. But in S4 classes, we use the @ to access S4 class object data like bee5@bee_size.

Subscribe My YouTube Channel:
https://www.youtube.com/channel/UCUE7VPo...F_BCoxFXIw

Join Our Million Dollar Trading Challenge:
https://www.doubledoji.com/million-dolla...challenge/
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)