RaukR 2025 • R Beyond the Basics
Marcin Kierczak
08-May-2025
require(R6)
require(S7)
. Still in dev phase.S4 classes are more advanced than S3 as you actually define the structure of the data within the object of your particular class:
.ext_gene <- setClass(
Class = "ext_gene", contains = "gene",
slots = c(gene = "gene", feature_name = "character", feature_value = "character")
)
ANK3 <- .ext_gene(
name = "ANK3", coords = c(1.4e6, 1.412e6),
feature_name = "num_introns", feature_value = "5"
)
str(ANK3)
Formal class 'ext_gene' [package ".GlobalEnv"] with 5 slots
..@ gene :Formal class 'gene' [package ".GlobalEnv"] with 2 slots
.. .. ..@ name : chr(0)
.. .. ..@ coords: num(0)
..@ feature_name : chr "num_introns"
..@ feature_value: chr "5"
..@ name : chr "ANK3"
..@ coords : num [1:2] 1400000 1412000
Preventing double class definition:
But to prevent this:
The variables within an S4 class are stored in the so-called slots. In the above example, we have 2 such slots: name and coords. Here is how to access them:
The power of classes lies in the fact that they define both the data types in particular slots and operations (functions) we can perform on them. Let us define a generic print function for an S4 class:
An S3 class object is one of R base types (e.g. integer) with class
attribute set:
str
MethodsSome S3 classes provide a custom str
, e.g.:
Have you ever wondered why print()
or summary()
work on many types (classes) of data?
They are so-called generics, i.e. functions and methods that operate on classes. They know which method to apply to which class thanks to the process of method dispatch.
The naming scheme for generics is: generic.class()
i.e. a generic that applies to the class
class.
Examples:
print.factor()
,print.default()
,print.data.frame()
.To see the code of a method:
To create an S3 class, simply give a name to a data structure:
OR
You can use some inheritance too:
Call:
lm(formula = log(mpg) ~ log(disp))
Coefficients:
(Intercept) log(disp)
5.3810 -0.4586
S C A R Y !
apply()
system_time()
user system elapsed
0.002 0.001 0.003
[1] 0.09831006 0.38424279 0.75600172 0.12177560 0.41474869
tidyverse
functions take data x
as the very first argument and return object similar to x
so that they can be chained by %>%
Even more patterns here.
One can build an S3 class on top of any existing base type, e.g. a named list:
require(R6)
,library(R6)
Person <- R6Class("Person",
public = list(
name = NULL,
hair = NULL,
initialize = function(name = NA, hair = NA) {
stopifnot(is.character(name), is.character(hair))
self$name <- name
self$hair <- hair
self$greet()
},
set_hair = function(val) {
self$hair <- val
},
greet = function() {
cat(paste0("Hello, my name is ", self$name, ".\n"))
}
)
)