S4 class is an improvement over the S3 class. They have a formally defined structure and a uniform way to create an object.
This adds safety to our code and prevents us from accidentally making naive mistakes.
Define S4 Class in R
In R, we use the setClass()
function to define a class.
Member variables in R are called slots. While defining a class, we need to set the name and the slots (along with class of the slot) it is going to have.For example,
setClass("Employee_Info", slots=list(name="character", age="numeric", role="character"))
Here, we have created a class named Employee_Info
with three slots (member variables): name, age, and role.
Create S4 Object in R
To create an object in R, we use the new()
function. For example,
student1 <- new("Student_Info", name = "Peter", age = 21, role = "Developer")
Here, we have created the object named student1 by providing the name of the class Student_Info
and value for all three slots inside new()
.
Example 1: S4 Class and Object in R
# create a class "Student_Info" with three member variables
setClass("Employee_Info", slots=list(name="character", age="numeric", role="character"))
# create an object of class
employee1 <- new("Employee_Info", name = "Peter", age = 21, role = "Developer")
# call employee1 object
employee1
Output
An object of class "Employee_Info" Slot "name": [1] "Peter" Slot "age": [1] 21 Slot "role": [1] "Developer"
Here, we have created an S4 class named Employee_Info
using the setClass()
function.
We then created an object named employee1
using the new()
function
new("Employee_Info", name = "Peter", age = 21, role = "Developer")
Here,
name
accepts"character"
value so, we have passed"Peter"
age
accepts"numeric"
value, so we passed numeric value 21role
accepts"character"
value so, we have passed"Developer"
Finally, we have called the object employee1.
Access S4 Class Slot in R
In R, we access slots using the @
operator. For example,
# access name slot of Employee_Info class
employee1@name # prints "Peter"
Here, we have accessed the name
slot of the Employee_Info
class using @
.
So "Peter"
gets printed.
Example: Access S4 Class slot
setClass("Employee_Info", slots=list(name="character", age="numeric", role="character"))
employee1 <- new("Employee_Info", name = "Peter", age = 21, role = "Developer")
# access name slot of Employee_Info
employee1@name # prints "Peter"
# access role slot of Employee_Info
employee1@role # prints "Developer"
Output
[1] "Peter" [1] "Developer"
Here,
employee1@name
- access name slot ofEmployee_Info
and prints"Peter"
employee1@role
- access role slot ofEmployee_Info
and prints"Developer"
Modify S4 Class Slot in R
We can use @
to access and assign a new value to a slot in R. For example,
# access and assign new value to role slot
employee1@role <- "Designer"
# print new slot value
employee@role
Here, the role slot value is changed from "Developer"
to "Designer"
.
Example: Modify S4 Class slot
setClass("Employee_Info", slots=list(name="character", age="numeric", role="character"))
employee1 <- new("Employee_Info", name = "Peter", age = 21, role = "Developer")
# access and modify name slot of Employee_Info
employee1@name <- "Jack"
# access and modify role slot of Employee_Info
employee1@role <- "Designer"
# print modified value for name slot
employee1@name # prints "Jack"
# print modified value for role slot
employee1@role # prints "Designer"
Output
[1] "Jack" [1] "Designer"
Here,
employee1@name <- "Jack"
- changes value of name slot from"Peter"
to"Jack"
.employee1@role <- "Designer"
- changes role slot from"Developer"
to"Designer"
.
S4 Generic Function and Method in R
As in the case of S3 class, methods for S4 class also belong to generic functions rather than the class itself.
Working with S4 generics is pretty much similar to S3 generics. So please visit S3 generics to get detailed information on generics.
We can list all the S4 generic functions and methods available, using the function showMethods()
:
# list all s4 generic methods
showMethods()
Output
Function: - (package base) Function: != (package base) ... ... Function: trigamma (package base) Function: trunc (package base)
After creating an object of the class, when we just write the name of the object in interactive mode, it prints the object. This is done using the S4 generic function show()
.
You can see this function in the above list. This function is the S4 analogy of the S3 print()
function.
# call object without show()
employee1
# call object with show()
show(employee1)
Here, in both case, the output will be the same
Example: Check if a function is a generic function
isS4(print)
# Output: [1] FALSE
isS4(show)
# Output: [1] TRUE
Here, we have used the isS4()
function to check if a function is a S4 generic function or not.
Since,
print
is not S4 generic function, the function returnsFALSE
show
is S4 generic function, the function returnsTRUE
Write Own Method in R
In R, we can write our own method using the setMethod()
function.
For example, we can implement our class method for the show()
generic as follows.
setMethod("show",
"Employee_Info",
function(obj) {
cat(obj@name, "\n")
cat(obj@age, "years old\n")
cat("Role:", obj@role, "\n")
}
)
Here, we have implemented our class method for the show()
generic.
Now, if we write out the name of the object in interactive mode as before, the above code is executed. For example,
setClass("Employee_Info", slots=list(name="character", age="numeric", role="character"))
employee1 <- new("Employee_Info", name = "Peter", age = 21, role = "Developer")
# create own method
setMethod("show",
"Employee_Info",
function(object) {
cat(object@name, "\n")
cat(object@age, "years old\n")
cat("Role:", object@role, "\n")
}
)
# call employee1 object
employee1
Output
Peter 21 years old Role: Developer
Here, we have created our own method for the show()
generic. We have passed object
as an argument.
We have used object
and @
to get values for name
, age
, and role
attributes of the Employee_Info
class.
Now this method will be called whenever we write an object name.
So the output will be:
Peter
21 years old
Role: Developer
Instead of
An object of class "Employee_Info"
Slot "name":
[1] "Peter"
Slot "age":
[1] 21
Slot "role":
[1] "Developer"