Object-Oriented R: S3
Prerequisites: Lists, Functions
R has several object systems. The oldest and most widely used is S3.
You use it constantly without noticing: print(), summary(), and
plot() behave differently for data frames, models, and factors because
of S3.
How S3 works
An S3 object is just an ordinary R object (usually a list) with a
class attribute. A generic function like print looks at the
class and calls the matching method, named generic.class:
new_money <- function(amount, currency = "USD") {
stopifnot(is.numeric(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
print.money <- function(x, ...) {
cat(sprintf("%.2f %s\n", x$amount, x$currency))
invisible(x)
}
format.money <- function(x, ...) sprintf("%.2f %s", x$amount, x$currency)
price <- new_money(19.9, "EUR")
price
class(price)
paste("Total:", format(price))
19.90 EUR
[1] "money"
[1] "Total: 19.90 EUR"
structure(..., class = "money")creates the object.print.moneyis theprintmethod for classmoney, so typingpricein the console uses it automatically.- A constructor function (
new_money) that validates inputs keeps objects consistent.
Writing your own generic
area <- function(shape, ...) UseMethod("area")
area.circle <- function(shape, ...) pi * shape$r^2
area.rectangle <- function(shape, ...) shape$w * shape$h
area.default <- function(shape, ...) stop("Don't know the area of a ", class(shape)[1])
c1 <- structure(list(r = 1), class = "circle")
r1 <- structure(list(w = 2, h = 3), class = "rectangle")
round(area(c1), 2)
area(r1)
[1] 3.14
[1] 6
UseMethod("area") dispatches to the method for the object's class, or
to area.default.
Inheritance
The class attribute can be a vector; R tries each class in order:
x <- structure(list(), class = c("premium_account", "account"))
inherits(x, "account")
[1] TRUE
methods(print) lists all print methods; methods(class = "lm") lists
everything you can do with a linear model.
When to use S3
S3 is simple and informal — ideal for giving your own data structures
friendly print, summary, and format methods, which is exactly what
most packages do. The next lesson covers the stricter alternatives.