Escolar Documentos
Profissional Documentos
Cultura Documentos
Kurt Hornik
September 30, 2017
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
2 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
Motivation 3 / 55
Needs in data analysis
I Support structural thinking (numeric vectors, factors, data frames, results of fitting a
model, . . . )
Motivation 4 / 55
Needs in data analysis
I Support structural thinking (numeric vectors, factors, data frames, results of fitting a
model, . . . )
I Support functional thinking (“generic” functions)
Motivation 4 / 55
Needs in data analysis
I Support structural thinking (numeric vectors, factors, data frames, results of fitting a
model, . . . )
I Support functional thinking (“generic” functions)
I Allow for simple extensibility (printing, plotting, summarizing, . . . )
Motivation 4 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S3 Classes 5 / 55
Basic idea
S3 Classes 6 / 55
Basic idea
S3 Classes 6 / 55
Basic idea
S3 Classes 6 / 55
Basic idea
S3 Classes 6 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S3 Classes 7 / 55
Manipulating the class info
I Function class() gets the class attribute, and there is a replacement function for setting
it:
R> x <- 1 : 3
R> x
[1] 1 2 3
S3 Classes 8 / 55
Manipulating the class info
I Function class() gets the class attribute, and there is a replacement function for setting
it:
R> x <- 1 : 3
R> x
[1] 1 2 3
R> class(x) <- "bar"
R> x
[1] 1 2 3
attr(,"class")
[1] "bar"
S3 Classes 8 / 55
Manipulating the class info
I Function class() gets the class attribute, and there is a replacement function for setting
it:
R> x <- 1 : 3
R> x
[1] 1 2 3
R> class(x) <- "bar"
R> x
[1] 1 2 3
attr(,"class")
[1] "bar"
I If e.g. class(x) is c("bar", "baz", "grr"), then x belongs to class bar and inherits
from baz, then grr, etc.
S3 Classes 8 / 55
Manipulating the class info
I Function class() gets the class attribute, and there is a replacement function for setting
it:
R> x <- 1 : 3
R> x
[1] 1 2 3
R> class(x) <- "bar"
R> x
[1] 1 2 3
attr(,"class")
[1] "bar"
I If e.g. class(x) is c("bar", "baz", "grr"), then x belongs to class bar and inherits
from baz, then grr, etc.
I Function unclass() removes the class(es)
S3 Classes 8 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S3 Classes 9 / 55
Method dispatch
S3 Classes 10 / 55
Method dispatch
S3 Classes 10 / 55
Method dispatch
S3 Classes 10 / 55
Method dispatch
S3 Classes 10 / 55
Creating generics
S3 Classes 11 / 55
Creating methods
I am here
S3 Classes 12 / 55
Explicitly invoking inheritance
Function NextMethod() can be used within methods to call the next method. E.g.,
R> test <- function(x) UseMethod("test")
R> test.c1 <- function(x) { cat("c1\n"); NextMethod(); x }
R> test.c2 <- function(x) { cat("c2\n"); NextMethod(); x }
R> test.c3 <- function(x) { cat("c3\n"); NextMethod(); x }
R> x <- 1
R> class(x) <- c("c1", "c2")
S3 Classes 13 / 55
Dispatching on other arguments
S3 Classes 14 / 55
Testing and coercion
No “formal” testing (predicate) for and coercion to S3 classes. By convention, is.bar() and
as.bar(). E.g.,
R> is.bar <- function(x) inherits(x, "bar")
R> as.bar <- function(x) if(is.bar(x)) x else bar(x)
S3 Classes 15 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S3 Classes 16 / 55
Motivation
Issues:
I How can we e.g. add or compare objects of a certain class?
I Or more generally, e.g. compare with objects not in the same class?
Need a dispatch mechanism for “operators” (such as "<") which works in both arguments!
S3 Classes 17 / 55
Group methods
Mechanism:
I Operators grouped in three categories (Math, Ops, Summary)
S3 Classes 18 / 55
Group methods
Mechanism:
I Operators grouped in three categories (Math, Ops, Summary)
I Invoked if the operands correspond to the same method, or one to a method that takes
precedence; otherwise, the default method is used.
S3 Classes 18 / 55
Group methods
Mechanism:
I Operators grouped in three categories (Math, Ops, Summary)
I Invoked if the operands correspond to the same method, or one to a method that takes
precedence; otherwise, the default method is used.
I Class methods dominate group methods.
S3 Classes 18 / 55
Group methods
Mechanism:
I Operators grouped in three categories (Math, Ops, Summary)
I Invoked if the operands correspond to the same method, or one to a method that takes
precedence; otherwise, the default method is used.
I Class methods dominate group methods.
I Dispatch info available: .Method, .Generic, .Group, .Class
S3 Classes 18 / 55
Existing group methods
S3 Classes 19 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S3 Classes 20 / 55
Internal generics
In addition to UseMethod dispatch and group methods, some functions dispatch “internally”
(DispatchOrEval() in the underlying C code of builtin functions):
I subscripting and subassigning ([, [[, $)
I length dim dimnames c unlist
I as.character as.vector
I many is.xxx functions for builtins data types xxx
S3 Classes 21 / 55
Strengths and weaknesses
S3 Classes 22 / 55
Strengths and weaknesses
S3 Classes 22 / 55
Strengths and weaknesses
S3 Classes 22 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S4 Classes 23 / 55
Basics
S4 Classes 24 / 55
Basics
S4 Classes 24 / 55
Basics
S4 Classes 24 / 55
Basics
S4 Classes 24 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S4 Classes 25 / 55
Basics
S4 Classes 26 / 55
Basics
S4 Classes 26 / 55
Basics
R> setClass("fungi",
+ representation(x = "numeric", y = "numeric",
+ species = "character"))
S4 Classes 26 / 55
Basics (ctd.)
S4 Classes 27 / 55
Basics (ctd.)
Slots:
Name: species x y
Class: character numeric numeric
Extends: "xyloc"
S4 Classes 28 / 55
Basics (ctd.)
S4 Classes 29 / 55
Basics (ctd.)
Slot "x":
[1] 0.01477997 0.24804353 0.31348032 0.38295164 0.99212496
Slot "y":
[1] 0.7494637 0.8528740 0.4887645 0.4091002 0.9832586
S4 Classes 29 / 55
Basics (ctd.)
S4 Classes 30 / 55
Basics (ctd.)
S4 Classes 31 / 55
Basics (ctd.)
Slot "x":
[1] 0.7643687 0.5292848 0.5072340
Slot "y":
[1] 0.25934291 0.03045488 0.43157476
S4 Classes 31 / 55
Validity checking
Can specify restrictions for “valid” objects via the validity argument to setClass or via
setValidity (note: sets to the value of the current version.)
R> ## A valid "xyloc" object has the same number
R> ## of x and y values:
R> .valid_xyloc_object <- function(object) {
+ nx <- length(object@x)
+ ny <- length(object@y)
+ if(nx == ny)
+ TRUE
+ else
+ sprintf("Unequal x, y lengths: %d, %d", nx, ny)
+ }
S4 Classes 32 / 55
Validity checking
Slots:
Name: x y
Class: numeric numeric
R> conditionMessage(tc)
S4 Classes 34 / 55
Prototypes
S4 Classes 35 / 55
Prototypes
S4 Classes 35 / 55
Prototypes
S4 Classes 35 / 55
Virtual classes
S4 Classes 36 / 55
Virtual classes
S4 Classes 36 / 55
Virtual classes
S4 Classes 36 / 55
Inheritance
Class A inherits from (or extends) class B if is(x, "B") is true whenever is(x, "A") is.
S4 Classes 37 / 55
Inheritance
Class A inherits from (or extends) class B if is(x, "B") is true whenever is(x, "A") is.
Can be determined using function extends():
R> extends("fungi", "xyloc")
[1] TRUE
S4 Classes 37 / 55
Testing and coercion
I Use general-purpose functions is() and as() for testing and coercion:
R> is(f1, "xyloc")
[1] TRUE
R> as(c(1, 2, 3, 4.4), "integer")
[1] 1 2 3 4
S4 Classes 38 / 55
Testing and coercion
I Use general-purpose functions is() and as() for testing and coercion:
R> is(f1, "xyloc")
[1] TRUE
R> as(c(1, 2, 3, 4.4), "integer")
[1] 1 2 3 4
I Corresponding information obtained from the class definition, or via setIs() and
setAs()
S4 Classes 38 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S4 Classes 39 / 55
Method dispatch
I Explicit setting of methods for certain signatures (the classes of the arguments used in the
dispatch)
S4 Classes 40 / 55
Method dispatch
I Explicit setting of methods for certain signatures (the classes of the arguments used in the
dispatch)
I Can use several arguments in the dispatch
S4 Classes 40 / 55
Method dispatch
I Explicit setting of methods for certain signatures (the classes of the arguments used in the
dispatch)
I Can use several arguments in the dispatch
I Can determine the method dispatched to with selectMethod()
S4 Classes 40 / 55
Creating generics
Typically by setting a method (which automatically makes a function generic with the old
definition as the default method).
Or explicitly using setGeneric().
S4 Classes 41 / 55
Creating methods
By using setMethod():
R> setMethod("show", "fungi",
+ function(object) cat("I am just a fungus.\n"))
[1] "show"
R> f1
I am just a fungus.
(Note: sets to the value of the current version if a named function is used.)
For more complicated signatures:
R> setMethod("plot", c("numeric", "factor"), .......)
S4 Classes 42 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
S4 Classes 43 / 55
Basics
S4 Classes 44 / 55
Group methods
Math log, sqrt, log10, cumprod, abs, acos, acosh, asin, asinh, atan,
atanh, ceiling, cos, cosh, cumsum, exp, floor, gamma, lgamma,
sin, sinh, tan, tanh, trunc
Math2 round signif
Ops Arith Compare [Logic]
Arith + - * / ^ %% %/%
Compare == != < <= >= >
Summary max, min, range, prod, sum, any, all
Complex Arg, Conj, Im, Mod, Re
S4 Classes 45 / 55
Outline
I Motivation
I S3 Classes
I Classes
I Generic and Method Functions
I Group Methods
I Odds and ends
I S4 Classes
I Classes and Inheritance
I Generic and Method Functions
I Group Methods
I Reference Classes
Reference Classes 46 / 55
Basics
Thus, the refclass object system behaves more like Java or C#.
Use them only where mutable state is absolutely required!
Reference Classes 47 / 55
Basics
A reference class has three main components, given by three arguments to setRefClass:
I contains, the classes which the class inherits from.
Reference Classes 48 / 55
Basics
A reference class has three main components, given by three arguments to setRefClass:
I contains, the classes which the class inherits from.
I fields are the equivalent of slots in S4. They can be specified as a vector of field names,
or a named list of field types.
Reference Classes 48 / 55
Basics
A reference class has three main components, given by three arguments to setRefClass:
I contains, the classes which the class inherits from.
I fields are the equivalent of slots in S4. They can be specified as a vector of field names,
or a named list of field types.
I methods are functions that operate within the context of the object and can modify its
fields.
Reference Classes 48 / 55
Example
A simple reference class for bank accounts with methods for withdrawal and deposit:
R> setRefClass("Account",
+ fields = list(balance = "numeric"),
+ methods =
+ list(deposit =
+ function(amount) {
+ ## The following string documents the method
+ "Deposit the given amount from the account"
+ balance <<- balance + amount
+ },
+ withdraw =
+ function(amount) {
+ "Withdraw the given amount from the account"
+ balance <<- balance - amount
+ }))
Reference Classes 49 / 55
Example
Class fields:
Name: balance
Class: numeric
Class Methods:
"withdraw", "deposit", "field", "trace", "getRefClass", "initFields", "copy",
"callSuper", ".objectPackage", "export", "untrace", "getClass", "show",
"usingMethods", ".objectParent", "import"
Reference Superclasses:
"envRefClass"
Reference Classes 50 / 55
Example
Reference Classes 51 / 55
Example
Reference Classes 51 / 55
Example
Reference Classes 51 / 55
Example
Reference Classes 51 / 55
Example
Reference Classes 51 / 55
Example
Call:
$withdraw(amount)
[1] 50
R> a1$field("balance")
[1] 50
Reference Classes 53 / 55
Example
The most important property of refclass objects is that they are mutable, or equivalently they
have reference semantics:
R> a2 <- a1
R> a2$deposit(10)
R> a1
(In the example, copies will always refer to the same account.)
Reference Classes 54 / 55
Cool stuff
R> setRefClass("Dist")
R> setRefClass("DistUniform",
+ c("a", "b"),
+ "Dist",
+ methods =
+ list(mean =
+ function() {
+ (a + b) / 2
+ }))
R> DistUniform <- getRefClass("DistUniform")
R> U01 <- DistUniform$new(a = 0, b = 1)
R> U01$mean()
[1] 0.5