Reading — step 1 of 5
Learn
~1 min readS4 Classes and Functional Programming
R has multiple OO systems. S4 is the formal one — explicit slots, type-checked, multi-dispatch. Used heavily in Bioconductor.
# Define a class with slots:
setClass("Person",
representation(
name = "character",
age = "numeric"
),
prototype = list(name = "", age = 0)
)
# Construct:
ada <- new("Person", name = "Ada", age = 36)
# Access slots with @ (not $):
ada@name # "Ada"
ada@age # 36
# Update slots:
ada@age <- 37
S4 generic + methods:
setGeneric("greet", function(x) standardGeneric("greet"))
setMethod("greet", "Person", function(x) {
sprintf("Hi, %s", x@name)
})
greet(ada) # "Hi, Ada"
Multi-dispatch — method resolved by ALL arguments:
setGeneric("combine", function(a, b) standardGeneric("combine"))
setMethod("combine", signature("numeric", "numeric"), function(a, b) a + b)
setMethod("combine", signature("character", "character"), function(a, b) paste(a, b))
combine(3, 4) # 7
combine("Hi", "World") # "Hi World"
Dispatch checks class of each argument — different from S3 (which only checks the first).
Validity functions:
setValidity("Person", function(object) {
if (object@age < 0) return("age cannot be negative")
TRUE
})
new("Person", name = "Bob", age = -5) # error
Inheritance with contains:
setClass("Employee",
contains = "Person",
representation(salary = "numeric"))
S4 vs S3:
- S3 — informal, fast, used by base R (
print,summary) - S4 — formal, slower, used when you need strict typing/multi-dispatch
- R5/R6 — reference semantics (mutable objects), more like Java
For most data analysis: S3 is fine. Reach for S4 when you're building a library that needs proper class hierarchies and validation.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…