R Reference | R Reference Class - r - learn r - r programming

- Reference class in R programming is similar to the object oriented programming we are used to seeing in common languages like C++, Java, Python etc.
- Defines and uses reference class objects.
- Unlike S3 and S4 classes, methods belong to class rather than generic functions.
- Reference class are internally implemented as S4 classes with an environment added to it.

r programming class object pass by reference
How to defined a reference class?
- Defining reference class is similar to defining a S4 class.
- Instead of setClass() we use the setRefClass() function.
>setRefClass("student")
- Member variables of a class, if defined, need to be included in the class definition.
- Member variables of reference class are called fields (analogous to slots in S4 classes).
- Following is an example to define a class called student with 3 fields, name, age and GPA.
>setRefClass("student", fields = list(name = "character", age = "numeric", GPA = "numeric"))
How to create a reference objects?
- The function setRefClass() returns a generator function which is used to create objects of that class.
> student <- setRefClass("student",
fields = list(name = "character", age = "numeric", GPA = "numeric"))
># now student() is our generator function which can be used to create new objects
> s <- student(name = "John", age = 21, GPA = 3.5)
> s
Referenceclassobject of class"student"
Field"name":
[1] "John"
Field"age":
[1] 21
Field"GPA":
[1] 3.5
How to access and modify fields?
- Fields of the object can be accessed using the $ operator.
>s$name
[1] "John"
>s$age
[1] 21
>s$GPA
[1] 3.5
- Similarly, it is modified by reassignment.
>s$name<- "Paul"
> s
Referenceclassobject of class"student"
Field"name":
[1] "Paul"
Field"age":
[1] 21
Field"GPA":
[1] 3.5
Warning Note:
- In R programming, objects are copied when assigned to new variable or passed to a function (pass by value).
For example.
># create list a and assign to b
> a <- list("x" = 1, "y" = 2)
> b <- a
># modify b
>b$y = 3
># a remains unaffected
> a
$x
[1] 1
$y
[1] 2
># only b is modified
> b
$x
[1] 1
$y
[1] 3
- But this is not the case with reference objects. Only a single copy exist and all variables reference to the same copy. Hence the name, reference.
># create reference object a and assign to b
> a <- student(name = "John", age = 21, GPA = 3.5)
> b <- a
># modify b
>b$name<- "Paul"
># a and b both are modified
> a
Referenceclassobject of class"student"
Field"name":
[1] "Paul"
Field"age":
[1] 21
Field"GPA":
[1] 3.5
> b
Referenceclassobject of class"student"
Field"name":
[1] "Paul"
Field"age":
[1] 21
Field"GPA":
[1] 3.5
- This can make some unwanted change in values and be the source of strange bugs.
- We need to keep this in mind while working with reference objects.
- To make a copy, we can use the copy() method made availabe to us.
># create reference object a and assign a’s copy to b
> a <- student(name = "John", age = 21, GPA = 3.5)
> b <- a$copy()
># modify b
>b$name<- "Paul"
># a remains unaffected
> a
Referenceclassobject of class"student"
Field"name":
[1] "John"
Field"age":
[1] 21
Field"GPA":
[1] 3.5
># only b is modified
> b
Referenceclassobject of class"student"
Field"name":
[1] "Paul"
Field"age":
[1] 21
Field"GPA":
[1] 3.5
Reference Methods
- Methods are defined for a reference class and do not belong to generic functions as in S3 and S4 classes.
- All reference class have some methods predefined because they all are inherited from the superclass envRefClass.
> student
Generatorforclass"student":
Class fields:
Name: name age GPA
Class: character numeric numeric
ClassMethods:
"callSuper", "copy", "export", "field", "getClass", "getRefClass",
"import", "initFields", "show", "trace", "untrace", "usingMethods"
ReferenceSuperclasses:
"envRefClass"
- We can see class methods like copy(), field() and show() in the above list.
- We can create our own methods for the class.
- This can be done during the class definition by passing a list of function definitions to methods argument of setRefClass().
student <- setRefClass("student",
fields = list(name = "character", age = "numeric", GPA = "numeric"),
methods = list(
inc_age = function(x) {
age <<- age + x
},
dec_age = function(x) {
age <<- age - x
}
)
)
- In the above section of our code, we defined two methods called inc_age() and dec_age(). These two method modify the field age.
- Note that we have to use the non-local assignment operator <<- since age isn't in the method's local environment.
- Using the simple assignment operator <- would have created a local variable called age, which is not what we want. R will issue a warning in such case.
- Here is a sample run where we use the above defined methods.
> s <- student(name = "John", age = 21, GPA = 3.5)
>s$inc_age(5)
>s$age
[1] 26
>s$dec_age(10)
>s$age
[1] 16