object-oriented in r
TRANSCRIPT
-
7/30/2019 Object-Oriented in R
1/138
Object-Oriented
programming in RSusana Eyheramendy
1
-
7/30/2019 Object-Oriented in R
2/138
Introduction
Object-oriented programming (OOP) hasbecome a widely used and valuable tool for
software engineering.
Its value derives from the fact that it is ofteneasier to design, write and maintain software
when there is some clear separation of thedata representation from the operations thatare to be performed on it.
2
-
7/30/2019 Object-Oriented in R
3/138
Introduction
In an OOP system, real physical things are generallyrepresented by classes, and methods (functions) arewritten to handle the different manipulations that
need to be performed on the objects.
Many peoples view if OOP is based on a class-centricsystem, in which classes define objects and there are
repositories for the methods that can act on thoseobjects.
R separates the class specification from thespecification of generic functions, its a function-
centric system. 3
-
7/30/2019 Object-Oriented in R
4/138
Introduction
R supports two internal OOP systems: S3and S4.
S3 is easy to use but can be made unreliablethrough nothing other than bad luck, or apoor choice of names.
S4 is better suited for developing largesoftware projects but has an increasedcomplexity of use.
4
-
7/30/2019 Object-Oriented in R
5/138
Introduction
Four general elements that an oop language should support:
Objects: encapsulate state information and control
behavior.
Classes: describe general properties for groups of
objects.
Inheritance: new classes can be defined in terms ofexisting classes.
Polymorphism: a (generic) function has differentbehaviors, although similar outputs, depending on the class
of one or more of its arguments.5
-
7/30/2019 Object-Oriented in R
6/138
Introduction
In S3, there is no formal specification for classesand hence there is a weak control of objects and
inheritance. The emphasis of the S3 system wason generic functions and polymorphism.
In S4, formal class definitions were included in
the language and based on these, morecontrolled software tools and paradigms for thecreation of objects and the handling ofinheritance were introduced.
6
-
7/30/2019 Object-Oriented in R
7/138
The basic of OOP
Classes describe the objects that will berepresented incomputer code.
A class specification details all the properties
that areneeded to describe an object.
An object is an instance of exactlyone class and it is theclass definition and representation that determine the
properties of the object. Instances of a class difer only intheir state.
Newclasses can be defined in terms of existing classes
through an operation calledinheritance.7
-
7/30/2019 Object-Oriented in R
8/138
The basic of OOP
Inheritance allows new classes to extend,often by adding new slots or by combining
two or more existing classes into a singlecompositeentity.
If a classAextends the classB, then we saythatAis a superclassofB, and equivalentlythatBis a subclass ofA.
No class can be its ownsubclass. A class isa subclass of each of its superclasses.
8
-
7/30/2019 Object-Oriented in R
9/138
The basic of OOP
If the language only allows a class to extend, at most,one class, then wesay that language has singleinheritance.
Computing the class hierarchy isthen very simple, sincethe resulting hierarchy is a tree and there is a single
unique path from any node to the root of the tree. Thispath yields the classlinearization.
In the S3 system, the class of an instance is determined
by the
values in theclass
attribute, which is a vector.9
-
7/30/2019 Object-Oriented in R
10/138
The basic of OOP
If thelanguage allows a class to directly
extend several classes, then we say that thelanguage supports multiple inheritance andcomputing the class linearizationis more
dicult.
S4 supports multiple dispatch.
10
-
7/30/2019 Object-Oriented in R
11/138
The basic of OOP
A method is a type of function that is invoked dependingon the class of oneor more of its arguments and this
process is called dispatch. While in some systems, such asS3, methods can be invoked directly, it is more commonfor them to be invoked via a generic function.
When a generic function isinvoked, the set of methods
that might apply must be sorted into a linearorder, withthe most specific method first and the least specificmethod last.This is often called method linearization andcomputing it depends on beingable to linearize the class
hierarchy. 11
-
7/30/2019 Object-Oriented in R
12/138
The basic of OOP If the language supports dispatching ona single argument, then
we say it has single dispatch. TheS3 system use single dispatch.
When the language supports dispatching onseveral arguments,we say that the language supports multiple dispatch andthe setof specific classes of the arguments for each formal parameterof the generic function is called the signature. S4 supportsmultiple dispatch.
With
multiple dispatch, the additional complication ofprecedence of the arguments arises. In particular, whenmethod selection depends on inheritance, theremay be morethan one superclass for which a method has been defined. Inthis case, a concept of the distance between the class and its
superclasses is used to guide selection.12
-
7/30/2019 Object-Oriented in R
13/138
The basic of OOP The evaluation process for a call to a generic function is
roughly as follows:
The actual classes of supplied arguments that match the
signature of the generic function are determined. Basedon these, the available methods areordered from mostspecific to least. Then, after evaluating any code supplied inthe generic, control is transferred to the most specific
method.
In S4, a generic function has a fixed set of named formalarguments and these formthe basis of the signature. Any callto the generic will be dispatched withrespect to itssignature. 13
-
7/30/2019 Object-Oriented in R
14/138
The basic of OOP:
inheritance
> setClass("Passenger", representation(name = "character",
+ origin = "character", destination = "character"))
[1] "Passenger"
> setClass("FreqFlyer", representation(ffnumber = "numeric"),
+ contains = "Passenger")
[1] "FreqFlyer"
Consider as an example of the S4 systemthe modeling of airline passengers.
We then say that theFreqFlyeris a subclass ofPassengerandthatPassengeris a superclass of
FreqFlyer. 14
-
7/30/2019 Object-Oriented in R
15/138
Exercise
Define a class for passenger names that has slots for the first name, middleinitial and last name. Change the definition of thePassengerclass to reflectyour new class. Does this change the inheritance properties of thePassengerclass or theFreqFlyerclass?
15
-
7/30/2019 Object-Oriented in R
16/138
The basic of OOP:
inheritance> getClass("FreqFlyer")Slots:
Name: ffnumber name origin
Class: numeric character character
Name: destination
Class: character
Extends: "Passenger"
> subClassNames("Passenger")
[1] "FreqFlyer"
> superClassNames("FreqFlyer")
[1] "Passenger"16
-
7/30/2019 Object-Oriented in R
17/138
The basic of OOP:
Dispatch A method is a specialized function that can
be applied to instances of one or more
classes (objects).
The process of determining the appropriatemethod to invoke is called dispatch.
A call to a function, such as plot, will invokea method that is determined by the class ofthe first argument in the call to plot.
17
-
7/30/2019 Object-Oriented in R
18/138
The basic of OOP:
Dispatch When a generic function is called, it must examine the
supplied arguments and determine the applicablemethods. All applicable methods are arranged frommost specific to least specific and the most specificmethod is invoked.
During evaluation, control may be passedto lessspecific methods by callingNextMethodin S3 and via
callNextMethodforS4.
18
-
7/30/2019 Object-Oriented in R
19/138
The basic of OOP:
Dispatch For example, consider a print method for passengers
that prints theirnames and flight details.
A print method for frequent flyers could simplyinvoke the passenger method, and then add a lineindicating the frequent flyernumber. Using this
approach, very little additional code is needed; and ifthe printing of passenger information is changed, theupdate is automaticallyapplied to printing of frequentflyer information.
19
-
7/30/2019 Object-Oriented in R
20/138
The basic of OOP:
Dispatch
With both S3 and S4, dispatching isimplemented through the use of genericfunctions.
20
-
7/30/2019 Object-Oriented in R
21/138
R
21
Everything you touch in Rranging from numbers to character strings
to matricesis an object.
R promotes encapsulation, which is packaging separate but related dataitems into one class instance. Encapsulation helps you keep track of
related variables, enhancing clarity.
R classes are polymorphic, which means that the same function call leads
to different operations for objects of different classes. For instance, acall to print() on an object of a certain class triggers a call to a print
function tailored to that class. Polymorphism promotes reusability.
R allows inheritance, which allows extending a given class to a more spe-
cialized class.
-
7/30/2019 Object-Oriented in R
22/138
The S3 system
S3 is the original R structure for classes
S3 is still the dominant class paradigm in R use today
Most of Rs built-in classes are of the S3 type
An S3 class consists of a list, with a class nameattribute and dispatch capability added, which enables
the use of generic functions S4 classes were developed later with the goal of
adding safety (cannot accidentally access a classcomponent that is not already in existence).
22
-
7/30/2019 Object-Oriented in R
23/138
The S3 system
Generic functions and methods are widelyused but there is little use of inheritance andclasses are quite loosely defined.
Some classes are internal or implicit andothers are specified explicitly, typically byusing the class attribute.
One determines the class of an object usingthe function class().
23
-
7/30/2019 Object-Oriented in R
24/138
The S3 system
Theclass attribute is a vector of character
values, each of which specifiesa particular
class. The most specific class comes first,followed by any less specific classes.
> x = 1 : 1 0
> class(x)
[1] "integer"
> dim(x) = c(2, 5)
> class(x)
[1] "matrix"
> attr(x, "class")
24
-
7/30/2019 Object-Oriented in R
25/138
The S3 system
A way of testing whether an S3 object is aninstance of a particular classis to use theinherits function.
> inherits x, "integer"
[1] FALSE
25
-
7/30/2019 Object-Oriented in R
26/138
Example
> x = list(name = "Josephine Biologist", origin = "SEA",
+ destination = "YXY")
> class(x) = "Passenger"
> y = list(name = "Josephine Physicist", origin = "SEA",+ destination = "YVR", ffnumber = 10)
> class(y) = c("FreqFlyer", "Passenger")
> inherits(x, "Passenger")
[1] TRUE
> inherits(x, "FreqFlyer")
[1] FALSE
> inherits(y, "Passenger")
[1] TRUE
26
-
7/30/2019 Object-Oriented in R
27/138
The S3 system
The functionis.object tests whether or
not an R object has aclassattribute.
> x = 1:10
> is.object(x)
[1] FALSE
> class(x) = "myint"
> is.object(x)
[1] TRUE
27
-
7/30/2019 Object-Oriented in R
28/138
The S3 system: Implicit
classes The earliest versions of the S language predate the
widespread use of object-oriented programmingand hence the class representations for some of themore primitive or basic classes do not use theclass attribute.
For example,functions and closures are implicitly of
classfunctionwhile matrices and arraysare implicitlyof classesmatrix and array, respectively.
28
-
7/30/2019 Object-Oriented in R
29/138
The S3 systemv v
[1] 1 2 3 4 5 6 7 8 9 10
> attributes(v)
NULL
> class(v)
[1] "integer"
> class(v) attributes(v)
NULL
> class(v)
[1] "character" 29
-
7/30/2019 Object-Oriented in R
30/138
OOP in the lm() Linear
Model function
30
> ?lm> x y lmout class(lmout)
[1] "lm"
> lmout
Call:
lm(formula = y ~ x)
Coefficients:
(Intercept) x
-3.0 3.5
-
7/30/2019 Object-Oriented in R
31/138
# S3 classes
library(car) # for data
mod.prestige
-
7/30/2019 Object-Oriented in R
32/138
S3 generic functions and
methods The generic function is responsible for setting upthe evaluation environment and for initiatingdispatch.
A generic function does this througha call toUseMethodthat initiates the dispatch on a single
argument, usuallythe first argument to the generic
function.
The generic is typically a verysimple function withonly two formal arguments, one often namedxand
theother the ... argument.32
-
7/30/2019 Object-Oriented in R
33/138
OOP in the lm() Linear
Model function
33
> ?lm> x y lmout class(lmout)
[1] "lm"
> lmout
Call:
lm(formula = y ~ x)
Coefficients:
(Intercept) x
-3.0 3.5
What happened here?In R terminology, the call tothe generic function print() was
dispatched to the method
print.lm() associated with the
class "lm".
S3 i f i d
-
7/30/2019 Object-Oriented in R
34/138
S3 generic functions and
methods Methods are regular functions and are identified by
their name, which is aconcatenation of the name ofthe generic and the name of the class that theyareintended to apply to, separated by a dot.
A simple generic function namedfunand a default
method are shown below. The stringdefaultis used
asif it were a class and indicates that the method is adefault method for thegeneric.
> fun = function(x, ...) UseMethod("fun")
> fun.default = function(x, ...) print("In the default method")
> fun(2)
[1] "In the default method"34
S3 i f i d
-
7/30/2019 Object-Oriented in R
35/138
S3 generic functions and
methodsConsider a class system with two classes,Foowhich extendsBar.Then we define two methods:fun.Fooandfun.Bar. We have
them print outa message, call the functionNextMethodand thenprint out a second message.
> fun.Foo = function(x) {
+ print("start of fun.Foo")
+ NextMethod()
+ print("end of fun.Foo")
+ }> fun.Bar = function(x) {
+ print("start of fun.Bar")
+ NextMethod()
+ print("end of fun.Bar")
+ }
35
S3 i f i d
-
7/30/2019 Object-Oriented in R
36/138
S3 generic functions and
methodsNow we can show how dispatch occurs by creating an instance that hasbothclasses and callingfunwith that instance as the first argument.
> x = 1
> class(x) = c("Foo", "Bar")
> fun(x)
[1] "start of fun.Foo"
[1] "start of fun.Bar"
[1] "In the default method"
[1] "end of fun.Bar"[1] "end of fun.Foo"
Notice that the call toNextMethodtransfers control to the next most specificmethod.
36
-
7/30/2019 Object-Oriented in R
37/138
OOP in the lm() Linear
Model function
37
> print
function(x, ...) UseMethod("print")
> print.lm
function (x, digits = max(3, getOption("digits") - 3), ...){
cat("\nCall:\n", deparse(x$call), "\n\n", sep = "")
if (length(coef(x))) {
cat("Coefficients:\n")
print.default(format(coef(x), digits = digits), print.gap = 2,
quote = FALSE)
}
else cat("No coefficients\n")
cat("\n")
invisible(x)
}
Printing depends oncontext, with a special
print function calledfor the lm class.
-
7/30/2019 Object-Oriented in R
38/138
OOP in the lm() Linear
Model function
38
What happens when we print this object with itsclass attribute removed?
> unclass(lmout)
$coefficients
(Intercept) x
-3.0 3.5
$residuals
1 2 3
0.5 -1.0 0.5
$effects
(Intercept) x
-6.928203 -4.949747 1.224745
$rank
[1] 2
...
The author of lm() decided tomake print.lm() much moreconcise, limiting it to printing
a few key quantities.
S3 i f ti d
-
7/30/2019 Object-Oriented in R
39/138
S3 generic functions and
methodsThe functionmethodsreports on all available methods for a givengeneric function but it does this simply by lookingat the names.
> methods("mean")
[1] mean.Date mean.POSIXct mean.POSIXlt
[4] mean.data.frame mean.default mean.difftime
One can also usemethodsto find all available methods for a given class. In
the code below we find all methods for the classglm.
> methods(class = "glm")[1] add1.glm* anova.glm[3] confint.glm* cooks.distance.glm*
[5] deviance.glm* drop1.glm*
[7] effects.glm* extractAIC.glm*
[9] family.glm* formula.glm*
[11] influence.glm* logLik.glm*
[13] model.frame.glm predict.glm
[15] print.glm residuals.glm
[17] rstandard.glm rstudent.glm
[19] summary.glm vcov.glm*
[21] weights.glm*
Non-visible functions are asterisked39
-
7/30/2019 Object-Oriented in R
40/138
The S3 system# S3 generic functions and methods
print # the print genericprint.lm # print method for "lm" objects
mod.prestigeprint(mod.prestige) # equivalent
print.lm(mod.prestige) # equivalent, but bad form
methods("print") # print methodsmethods(class="lm") # methods for objects of class "lm"
[1] add1.lm* alias.lm* anova.lm case.names.lm*[5] confint.lm* cooks.distance.lm* deviance.lm* dfbeta.lm*
[9] dfbetas.lm* drop1.lm* dummy.coef.lm* effects.lm*[13] extractAIC.lm* family.lm* formula.lm* hatvalues.lm[17] influence.lm* kappa.lm labels.lm* logLik.lm*[21] model.frame.lm model.matrix.lm plot.lm predict.lm[25] print.lm proj.lm* residuals.lm rstandard.lm[29] rstudent.lm simulate.lm* summary.lm variable.names.lm*[33] vcov.lm*
Non-visible functions are asterisked 40
-
7/30/2019 Object-Oriented in R
41/138
-
7/30/2019 Object-Oriented in R
42/138
Writing S3 classes
A class instance is created by forming a list,
with the components of the list being themember variables of the class.
The class attribute is set by hand by using
the attr() or class() function.
42
-
7/30/2019 Object-Oriented in R
43/138
Writing S3 classes
43
> lm
...
z
-
7/30/2019 Object-Oriented in R
44/138
Writing S3 classes
44
> j class(j) attributes(j) # let's check
$names
[1] "name" "salary" "union"
$class
[1] "employee"
> j
$name
[1] "Joe"
$salary
[1] 55000
$union
[1] TRUE
attr(,"class")
[1] "employee"Before we write a print
method for this class,lets see what happens
when we call the default
print():
Essentially,j was
treated as a list for
printing purposes
-
7/30/2019 Object-Oriented in R
45/138
Writing S3 classes
45
Now lets write our own print method:
print.employee methods(,"employee")
[1] print.employee
Or, of course, we can simply try it out:
> j
Joe
salary 55000
union member TRUE
-
7/30/2019 Object-Oriented in R
46/138
Using inheritance
The idea of inheritance is to form newclasses as specialized versions of old ones.
For example, we could form a new classdevoted to hourly employees,hrlyemployee, as a subclass of employee,as follows:
46
k
-
7/30/2019 Object-Oriented in R
47/138
S3 system: group
generic The S3 object system has the capability for defining
methods for groupsof functions simultaneously.
These tools are mainly used to define methods
forthree defined sets of operators.
This means that operators such as == or
-
7/30/2019 Object-Oriented in R
48/138
Group generic functions
48
Group Functions
Math abs, acos, acosh, asin, asinh, atan,atanh, ceiling, cos, cosh, cumsum, exp,floor, gamma, lgamma, log, log10, round,signif, sin, sinh, tan, tanh, trunc
Summary all, any, max, min, prod, range, sum
Ops +, -, *, /, ^, < , >, =, !=, ==, %%,%/%, &, |, !
-
7/30/2019 Object-Oriented in R
49/138
Group generic functions
It is possible to write methods specific
toany function within a group and then amethod defined for a single memberofgroup takes precedence over the group
method.
49
-
7/30/2019 Object-Oriented in R
50/138
The S3 system
# S3 "inheritance"
mod.mroz
-
7/30/2019 Object-Oriented in R
51/138
The S3 system# Example: a logistic-regression function
lreg3
-
7/30/2019 Object-Oriented in R
52/138
-
7/30/2019 Object-Oriented in R
53/138
The S3 systemsummary # summary generic
summary.lreg3
-
7/30/2019 Object-Oriented in R
54/138
The S3 system# writing a generic function
names(summary(mod.prestige))rsq
-
7/30/2019 Object-Oriented in R
55/138
S3 example: A class for storingupper triangular matrices
We will write an R class ut for uppertriangular matrices (squared matrices whose
elements below the diagonal are zeros). The motivation is to save storage space.
For example, the matrix
will be stored in > mat
-
7/30/2019 Object-Oriented in R
56/138
3
-
7/30/2019 Object-Oriented in R
57/138
S3 example: A class for storingupper triangular matrices
57
21 # uncompress utmat to a full matrix
22 expandut
-
7/30/2019 Object-Oriented in R
58/138
S3 example: A class for storingupper triangular matrices
58
39 # multiply one ut matrix by another, returning another ut instance;40 # implement as a binary operation
41 "%mut%"
-
7/30/2019 Object-Oriented in R
59/138
S3 example: A class for storingupper triangular matrices
59
column i of theproduct can be expressed as a linear combination of the columns ofthe first factor.
1 2 3
0 1 2
0 0 5
4 3 2
0 1 2
0 0 1
=
4 5 9
0 1 4
0 0 5
The third column of the product can be calculated as
2
1
0
0
+ 2
2
1
0
+ 1
3
2
5
-
7/30/2019 Object-Oriented in R
60/138
S3 E l A d
-
7/30/2019 Object-Oriented in R
61/138
S3 Example: A procedure
for polynomial regression
61
The class "polyreg" aims to deal with this issue. It fits polynomials of
various degrees but assesses fits via cross-validation to reduce the risk
of overfitting.
In this form of cross-validation, known as the leaving-one-out method,
for each point we fit the regression to all the data except this
observation, and then we predict that observation from the fit.
An object of this class consists of outputs from the various regression
models, plus the original data.
-
7/30/2019 Object-Oriented in R
62/138
S3 E l A d
-
7/30/2019 Object-Oriented in R
63/138
S3 Example: A procedure
for polynomial regression
63
22 # pr n or an o ec s o c ass po yreg : pr n
23 # cross-validated mean-squared prediction errors
24 print.polyreg
-
7/30/2019 Object-Oriented in R
64/138
S3 Example: A procedure
for polynomial regression
64
39 orms ma r x o powers o e vec or x, roug egree g
40
powers
-
7/30/2019 Object-Oriented in R
65/138
S3 Example: A procedure
for polynomial regression
65
50 # finds cross-validated predicted values; could be made much faster via
51 # matrix-update methods
52 lvoneout
-
7/30/2019 Object-Oriented in R
66/138
S3 Example: A procedure
for polynomial regression
66
65 # polynomial function of x, coefficients cfs
66 poly
-
7/30/2019 Object-Oriented in R
67/138
67
37 # generic plot(); plots fits against raw data
38 plot.polyreg
-
7/30/2019 Object-Oriented in R
68/138
S4 classes
68
Some programmers feel that S3 does not provide the safety normally associated with OOP.
For example, consider our earlier employee database example where our class "employee"had three fields: name, salary, and union. Here are some possible mishaps:! We forget to enter the union status.! We misspell union as onion.! We create an object of some class other than "employee" but accidentally set its classattribute to "employee".
In each of these cases, R will not complain.
The goal of S4 is to elicit a complaint and prevent such accidents.
-
7/30/2019 Object-Oriented in R
69/138
Overview between the differencesbetween S3 and S4 classes
69
Operation S3 S4
Define class Implicit in constructor code setClass()Create object Build list, set class attr new()Reference member variable $ @Implement generic f() Define f.classname() setMethod()
Declare generic UseMethod() setGeneric()
-
7/30/2019 Object-Oriented in R
70/138
-
7/30/2019 Object-Oriented in R
71/138
71
Now lets create an instance of this class, for Joe, using new(), abuilt-in constructor function for S4 classes:
Writing S4 classes
> joe joeAn object of class "employee"
Slot "name":
[1] "Joe"
Slot "salary":
[1] 55000
Slot "union":
[1] TRUE
Note that the member variables are called slots, referenced via the @ symbol.
-
7/30/2019 Object-Oriented in R
72/138
72
Writing S4 classes
> joe@salary
[1] 55000
We can also use the slot() function, say, as another way to query Joes
salary:
> slot(joe,"salary")
[1] 55000
-
7/30/2019 Object-Oriented in R
73/138
73
We can assign components similarly. Lets give Joe a raise:
> joe@salary joeAn object of class "employee"
Slot "name":
[1] "Joe"
Slot "salary":
[1] 65000
Slot "union":
[1] TRUE
Writing S4 classes
-
7/30/2019 Object-Oriented in R
74/138
Implementing a generic
-
7/30/2019 Object-Oriented in R
75/138
Implementing a generic
function on an S4 class
75
To define an implementation of a generic function on an S4 class, use
setMethod().
Lets do that for our class "employee" here.
Well implement the show() function, which is the S4 analog of S3s
generic "print".
Implementing a generic
-
7/30/2019 Object-Oriented in R
76/138
Implementing a generic
function on an S4 class
76
In R, when you type the name of a variable while in interactive mode, the value of the
variable is printed out:
> joe
An object of class "employee"Slot "name":
[1] "Joe"
Slot "salary":
[1] 88000
Slot "union":[1] TRUE
-
7/30/2019 Object-Oriented in R
77/138
-
7/30/2019 Object-Oriented in R
78/138
S4 system The S4 system was designed to overcome some of
the deficiencies of theS3 system as well as to provideother functionality that was simply missingfrom theS3 system.
Among the major changes between S3 and S4are theexplicit representation of classes, together with toolsthat support programmatic inspection of the class
definitions and properties.
Multipledispatch is supported in S4, but not in S3, andS4 methods are registereddirectly with the
appropriate generic. 78
-
7/30/2019 Object-Oriented in R
79/138
-
7/30/2019 Object-Oriented in R
80/138
S4 system: classesA class definition specifies the structure, inheritance and initialization ofinstances ofthat class. A class is defined by a call to the functionsetClass.The following
arguments can be specified in the calltosetClass:
Classa character string naming the class.
representationa named vector of types or classes. The names correspondto the slot namesin the class and the types indicate what type of valuecan be stored in the slot.
containsa character vector of class names, indicating the classes extendedor subclassed bythe new class.
prototypean object (usually a list) providing the default data for the slotsspecified in therepresentation.
validitya function that checks the validity of instances of the class. It mustreturn eitherTRUE
or a character vector describing how the object isinvalid.80
-
7/30/2019 Object-Oriented in R
81/138
S4 system: classes
Once a class has been defined by a call tosetClass, it is possible to createinstances of
the class through calls tonew.
Theprototype argument can beused to
define default values to use for the diferent
components of the class.Prototype values canbe overridden by expressly setting the value
for the slotin the call tonew.
81
-
7/30/2019 Object-Oriented in R
82/138
-
7/30/2019 Object-Oriented in R
83/138
-
7/30/2019 Object-Oriented in R
84/138
-
7/30/2019 Object-Oriented in R
85/138
Example
85
> setClass("B", contains = "A", representation(s2 = "character"),
+ prototype = list(s2 = "hi"))
[1] "B"
> myB = new("B")
> myB
An object of class "B"
Slot "s2":
[1] "hi"
Slot "s1":
[1] 0
-
7/30/2019 Object-Oriented in R
86/138
S4 system: classes
Classes can be removed using the functionremoveClass. However, this isnot especially useful
since you cannot remove classes from attachedpackages.
TheremoveClassis most useful when experimentingwith class creation interactively.
86
-
7/30/2019 Object-Oriented in R
87/138
Example
87
> setClass("Ohno", representation(y = "numeric"))
[1] "Ohno"
" "Slots:
Name: y
Class: numeric
> removeClass("Ohno")
[1] TRUE
-
7/30/2019 Object-Oriented in R
88/138
S4 system: classes
Once a class has been defined, there are anumber of software tools thatcan be usedto find out about that class.
These include:
getSlotsthat willreport the slot names andtypes,
the functionslotNamesthat will report only
the slot names.
88
-
7/30/2019 Object-Oriented in R
89/138
Example
89
> getSlots("A")
s1
"numeric"
> slotNames("A")
[1] "s1"
-
7/30/2019 Object-Oriented in R
90/138
-
7/30/2019 Object-Oriented in R
91/138
Example
91
> extends("B")
[1] "B" "A"> extends("B", "A")
[1] TRUE
> extends("A", "B")
[1] FALSE
> superClassNames("B")
[1] "A"
> subClassNames("A")
[1] "B"
-
7/30/2019 Object-Oriented in R
92/138
S4 system: classes
These functions also provide information about built-in classes that
havebeen converted viasetOldClass.
92
> getClass("matrix")
No Slots, prototype of class "matrix"
Extends:
Class "array", directly
Class "structure", by class "array", distance 2
Class "vector", by class "array", distance 3, with explicit co
erce
Known Subclasses:
Class "array", directly, with explicit test and coerce
> extends("matrix")
[1] "matrix" "array" "structure" "vector"
-
7/30/2019 Object-Oriented in R
93/138
S4 system: classes
To determine whether or not a class hasbeen defined, useisClass.
Youcan test whether or not an R object isan instance of an S4 class usingisS4.
All S4 objects should also returnTRUEfor
is.object, but so will any objectwith aclass
attribute.
93
-
7/30/2019 Object-Oriented in R
94/138
E l
-
7/30/2019 Object-Oriented in R
95/138
Example
95
> myb = new("B")
> as(myb, "A")
An object of class "A"
Slot "s1":
[1] 0
-
7/30/2019 Object-Oriented in R
96/138
-
7/30/2019 Object-Oriented in R
97/138
-
7/30/2019 Object-Oriented in R
98/138
E l
-
7/30/2019 Object-Oriented in R
99/138
Example
99
> setClass("Ex1", representation(s1 = "numeric"),
prototype = prototype(s1 = rnorm(10)))
[1] "Ex1"
> b = new("Ex1")
> b
An object of class "Ex1"
Slot "s1":[1] -1.3730 -0.5483 0.2648 0.0487 1.4423 0.0283 1.1793
[8] -1.6695 -0.0536 0.0729
E l
-
7/30/2019 Object-Oriented in R
100/138
Example
100
> bb = getClass("B")
> bb@prototype
attr(,"s2")
[1] "hi"
attr(,"s1")[1] 0
E l
-
7/30/2019 Object-Oriented in R
101/138
ExampleIn the example below, we define two new classes, one a simple class,W,and then a class that isa subclass of bothA, defined earlier, andW. Whencreating new instances ofWandA,wemade use of named arguments to theinitialize method, but when creating a new instance of theWAclass, we usedthe unnamed variant and supplied instances of the superclasses.
101
> setClass("W", representation(c1 = "character"))
[1] "W"
> setClass("WA", contains = (c("A", "W")))
[1] "WA"
> a1 = new("A", s1 = 20)
> w1 = new("W", c1 = "hi")
> new("WA", a1, w1)
An object of class "WA"
Slot "s1":
[1] 20
Slot "c1":
[1] "hi"
T f l
-
7/30/2019 Object-Oriented in R
102/138
Types of classes
A class can be instantiable or virtual.
Direct instances of virtual classescannot becreated.
One can test whether or not a class is
virtual using isVirtualClass().
102
-
7/30/2019 Object-Oriented in R
103/138
-
7/30/2019 Object-Oriented in R
104/138
-
7/30/2019 Object-Oriented in R
105/138
S4 generic functions and
-
7/30/2019 Object-Oriented in R
106/138
S ge e c u ct o s a
methods In almost all cases the body of the function
suppliedas thedefargument will be a call to
standardGeneric since this function isused to:
dispatch to methods based on the suppliedarguments to the generic function and
it also establishes a default method that willbe used ifno function with matching signatureis found.
106
-
7/30/2019 Object-Oriented in R
107/138
-
7/30/2019 Object-Oriented in R
108/138
S4 generic functions and
-
7/30/2019 Object-Oriented in R
109/138
g
methods Any argument passed through the . . . argument
cannot be dispatched on.
It is possible to have named arguments that are notpart of the signature of the generic function. This is
achieved by explicitly stating the signature for
thegeneric function using thesignatureargument in the
call tosetGeneric.
109
E l
-
7/30/2019 Object-Oriented in R
110/138
Example
110
> setGeneric("genSig", signature = c("x"), function(x,
y = 1) standardGeneric("genSig"))
[1] "genSig"
> setMethod("genSig", signature("numeric"), function(x,
y = 20) print(y))
[1] "genSig"
> genSig(10)
[1] 20
-
7/30/2019 Object-Oriented in R
111/138
-
7/30/2019 Object-Oriented in R
112/138
Evaluation model for
-
7/30/2019 Object-Oriented in R
113/138
generic functions When the generic function is invoked, the supplied
arguments are matched to the arguments of the
generic function; those that correspond toargumentsin the signature of the generic areevaluated.
Once evaluation of the generic function begins, allmethods registered withthe generic function areinspected and the applicable methods aredetermined.
113
Evaluation model for
-
7/30/2019 Object-Oriented in R
114/138
generic functions A method is applicable if for all arguments in
its signature, the class specified in themethod either matches the class of the
supplied argument or is asuperclass of theclass of the supplied argument.
The applicable methods areordered from
most specific to least specific. Dispatch isentirely determinedby the signature and theregistered methods at the time evaluation ofthe generic function begins.
114
-
7/30/2019 Object-Oriented in R
115/138
The syntax of method
-
7/30/2019 Object-Oriented in R
116/138
y
declaration
UseANYif the method will accept any value
for that argument.
The classmissing is appropriate when themethod will handle some, but not all, of the
arguments in the signature of the generic.
116
The syntax of method
-
7/30/2019 Object-Oriented in R
117/138
y
declaration When . . . is an argument to the generic function,
you can define methodswith named arguments that
will be handled by the . . . argument to the genericfunction. But some care is needed because thesearguments, in some sense,do not count.
There can be only one method, with any givensignature (set ofclasses defined for the formalarguments to the generic), regardless of whetherornot other argument names match.
117
Example
-
7/30/2019 Object-Oriented in R
118/138
Example
118
> setGeneric("bar", function(x, y, ...) standardGeneric("bar"))
[1] "bar"
> setMethod("bar", signature("numeric", "numeric"),
function(x, y, d) print("Method1"))
[1] "bar"
> ##removes the method above
> setMethod("bar", signature("numeric", "numeric"),
function(x, y, z) print("Method2"))
[1] "bar"
> bar(1,1,z=20)[1] "Method2"
> bar(2,2,30)
[1] "Method2"
-
7/30/2019 Object-Oriented in R
119/138
S4 system: Accessor
-
7/30/2019 Object-Oriented in R
120/138
y
functionsTo create an accessor function for this slot, wecreate a generic function namedaand a method for instances of the classFoo.
120
> setClass("Foo", representation(a = "ANY"))
[1] "Foo"
> setGeneric("a", function(object) standardGeneric("a"))
[1] "a"
> setMethod("a", "Foo", function(object) object@a)
[1] "a"
> b = new("Foo", a = 10)
> a(b)
[1] 10
-
7/30/2019 Object-Oriented in R
121/138
-
7/30/2019 Object-Oriented in R
122/138
-
7/30/2019 Object-Oriented in R
123/138
The S4 system
-
7/30/2019 Object-Oriented in R
124/138
The S4 system
show # the S4 generic function show
# defining an S4 methodsetMethod("show", signature(object="lreg4"),
definition=function(object){
coef
-
7/30/2019 Object-Oriented in R
125/138
The S4 system
setMethod("summary", signature(object="lreg4"),definition=function(object, ...)
{b
-
7/30/2019 Object-Oriented in R
126/138
The S4 system# Lexical scope
f
-
7/30/2019 Object-Oriented in R
127/138
The S4 system# a function that returns a closure (function +environment)
makePower
-
7/30/2019 Object-Oriented in R
128/138
method invocation When a generic function is invoked, the classes of allsupplied argumentsthat are in the signature of thegeneric function form thetarget signature.
Amethod is said tobe applicablefor this targetsignature if for every argumentin the signature theclass specified by the method is the same as the classofthe corresponding supplied argument, a superclass
of that class, or has class ANY.
To order the applicable methods, we need a metricon the classes.
128
-
7/30/2019 Object-Oriented in R
129/138
-
7/30/2019 Object-Oriented in R
130/138
Finding methods
-
7/30/2019 Object-Oriented in R
131/138
Finding methods
We will often need to be able to determinewhichmethods are registered with aparticular generic function.
At other timeswe will want to be able todetermine whether a particular signaturewill behandled by a generic.
Functionality of this sort is provided by thefunctionslisted next.
131
Finding methods
-
7/30/2019 Object-Oriented in R
132/138
Finding methods
showMethodsshows the methods for one or moregeneric functions. Theclass argument can be used to ask forall methods that have a particular class in their signature.
The output is printed tostdoutby default andcannot easilybe captured for programmatic use.
getMethodreturns the method for a specific generic
function whose signature is congruent with the specifiedsignature. An error is thrown if nosuch method exists.
findMethodreturns the packages in the search path thatcontain a definitionfor the generic and signature specified.
132
Finding methods
-
7/30/2019 Object-Oriented in R
133/138
Finding methods
selectMethodreturns the method for a specific genericfunction and signature, but difers fromgetMethodin that
inheritance is used to identify amethod.
existsMethodtests for a method with a congruent signature(to that provided) registered with the specified genericfunction. Noinheritanceisused. Returns eitherTRUEorFALSE.
hasMethod
tests for a method with a congruent signature forthe specifiedgeneric function. It seems that this would alwaysreturnTRUE(sincethere must be a default method). It does return
FALSEif there is nogeneric function, but it seems that there are
better ways to handle that.133
Finding Documentation
-
7/30/2019 Object-Oriented in R
134/138
Finding Documentation
Either a direct call tohelpor the use of the?operator will obtain the helppage for most functions.
To find out about classes an infix syntax is used, forexample, the syntax for displayingthe help page forthegraphclass, from thegraphpackage is:
class?graph
help("graph-class")
134
Finding Documentation
-
7/30/2019 Object-Oriented in R
135/138
Finding Documentation
Help for generic functions requires no special syntax;one just looks for help on the name of the generic
function. The syntax for two diferent ways to find the help
page for a method forthenodesgeneric function, for
an argument of classgraphNEL.
method?nodes("graphNEL")
help("nodes,graphNEL-method")
135
Finding Documentation
-
7/30/2019 Object-Oriented in R
136/138
Finding Documentation
library(RBioinf)
S4Help()
The function takes the name of either a S4 generic
functionor a S4 class and provides a selection menu tochoose a help page.
136
Managing S3 and S4
-
7/30/2019 Object-Oriented in R
137/138
together
Testing for inheritance is done diferentlybetween S3 and S4. The formeruses thefunctioninheritswhile the latter usesis.
137
Managing S3 and S4
-
7/30/2019 Object-Oriented in R
138/138
together The functionasS4can be used to allow aninstance of an S3 class to be passed toan S4method.
> x = 1> setClass("A", representation(s1 = "numeric"))
[1] "A"
> setMethod("+", c("A", "A"), function(e1, e2) print("howdy"))
[1] "+"
> class(x) = "A"
> x + x
[1] 2
attr(,"class")