Object-Oriented programming in R
We use it without knowing it, nor worrying about it.
A bit of vocabulary : object, class, attribute, method, inheritance, polymorphism.
Two frameworks:
- S3 (“old-style”, widely used in base packages)
- S4 (“formal classes”, since R 1.7, widely used in Bioconductor).
Another framework called R5 is under development.
S3 framework
A 'class' is a label attached to an object. Every object in R has a class (“numeric”, “matrix”, “lm”, “factor”…).
Method dispatch
Example of the summary() function. Applied on different objects gives different outputs. Many summary.“classname”() defined, for each class.
summary
## function (object, ...)
## UseMethod("summary")
## <bytecode: 0xaa03898>
## <environment: namespace:base>
methods("summary")
## [1] summary.aov summary.aovlist
## [3] summary.aspell* summary.connection
## [5] summary.data.frame summary.Date
## [7] summary.default summary.ecdf*
## [9] summary.factor summary.ggplot*
## [11] summary.glm summary.infl
## [13] summary.lm summary.loess*
## [15] summary.loglm* summary.manova
## [17] summary.matrix summary.mlm
## [19] summary.negbin* summary.nls*
## [21] summary.packageStatus* summary.PDF_Dictionary*
## [23] summary.PDF_Stream* summary.polr*
## [25] summary.POSIXct summary.POSIXlt
## [27] summary.ppr* summary.prcomp*
## [29] summary.princomp* summary.rlm*
## [31] summary.srcfile summary.srcref
## [33] summary.stepfun summary.stl*
## [35] summary.table summary.tukeysmooth*
## [37] summary.XMLInternalDocument*
##
## Non-visible functions are asterisked
Non-visible functions can be accessed by getAnywhere(“functionname”)
summary.loess()
## Error: impossible de trouver la fonction "summary.loess"
getAnywhere(summary.loess)
## A single object matching 'summary.loess' was found
## It was found in the following places
## registered S3 method for summary from namespace stats
## namespace:stats
## with value
##
## function (object, ...)
## {
## class(object) <- "summary.loess"
## object
## }
## <bytecode: 0xb0a0108>
## <environment: namespace:stats>
Access all methods of a class.
methods(class = "lm")
## [1] add1.lm* alias.lm* anova.lm
## [4] case.names.lm* confint.lm* cooks.distance.lm*
## [7] deviance.lm* dfbeta.lm* dfbetas.lm*
## [10] drop1.lm* dummy.coef.lm* effects.lm*
## [13] extractAIC.lm* family.lm* formula.lm*
## [16] fortify.lm* hatvalues.lm influence.lm*
## [19] kappa.lm labels.lm* logLik.lm*
## [22] model.frame.lm model.matrix.lm nobs.lm*
## [25] plot.lm predict.lm print.lm
## [28] proj.lm* qr.lm* residuals.lm
## [31] rstandard.lm rstudent.lm simulate.lm*
## [34] summary.lm variable.names.lm* vcov.lm*
##
## Non-visible functions are asterisked
Creating an S3 object
Example of the mygsea2 package.
# Create a list
z <- list()
# Label it with the correct class
class(z) <- "gsea"
# Create the methods the user of the class/object will need
print.gsea <- function(object) {
}
# If needed, create a new generic method
reduce.gsea <- function(object) {
}
reduce <- function(object) UseMethod("reduce")
Caution : the user can easily access attributes directly, modify them… and R will not complain!
S4 framework
Based on the same “method dispatch” idea than S3, but more formal.
setClass("GSEA", representation(nperms = "numeric"), contains = "genelist",
validity = function(object) {
})
gsea <- new("GSEA", nperms = 1000)
Checks are made for the validity of any created object. Properties include a name, representation, inheritance, prototype, validation(), etc. Attributes are stored in slots, similar to the components of a list for a S3 object, but use @ to “enter” the attributes of an object. S3 use print(), S4 use show(). “ANY” is the basic inheritance.
One can choose whichever one wants, but in any case, avoid mixing S3 and S4.
How to access information in an unknown object?
- class(object)
- look at documentation
- find if S3 or S4 with names(object) or isS4(object)
- look at the methods available for the object with methods(class=“class”) or showMethods(class=“class”)
- look at the attributes using $ or @
- if needed, look at a method's source code to see how it handles the attributes (method.class or getMethods(“method”, “class”) )
R5 framework
Still under development… See ?ReferenceClasses and http://adv-r.had.co.nz/R5.html

This work by Celine Hernandez is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.