| 71366 |
jmc |
1 |
\name{Introduction}
|
|
|
2 |
\alias{Introduction}
|
|
|
3 |
|
|
|
4 |
\title{Basic use of S4 Methods and Classes}
|
|
|
5 |
|
|
|
6 |
\description{
|
|
|
7 |
The majority of applications using methods and classes will be in \R
|
|
|
8 |
packages implementing new computations for an application, using new \emph{classes}
|
|
|
9 |
of objects that represent the data and results.
|
|
|
10 |
Computations will be implemented using \emph{methods} that implement
|
|
|
11 |
functional computations when one or more of the arguments is an object
|
|
|
12 |
from these classes.
|
|
|
13 |
|
|
|
14 |
Calls to the functions \code{\link{setClass}()} define the new classes;
|
|
|
15 |
calls to \code{\link{setMethod}} define the methods.
|
|
|
16 |
These, along with ordinary \R computations, are sufficient to get
|
|
|
17 |
started for most applications.
|
|
|
18 |
|
|
|
19 |
Classes are defined in terms of the data in them and what other
|
|
|
20 |
classes of data they inherit from.
|
|
|
21 |
Section \sQuote{Defining Classes} outlines the basic design of new classes.
|
|
|
22 |
|
|
|
23 |
Methods are \R functions, often implementing basic computations as
|
|
|
24 |
they apply to the new classes of objects.
|
|
|
25 |
Section \sQuote{Defining Methods} discusses basic requirements and
|
|
|
26 |
special tools for defining methods.
|
|
|
27 |
|
|
|
28 |
The classes discussed here are the original functional classes.
|
|
|
29 |
\R also supports formal classes and methods similar to those in other
|
|
|
30 |
languages such as Python, in which methods are part of class
|
|
|
31 |
definitions and invoked on an object.
|
|
|
32 |
These are more appropriate when computations expect references to
|
|
|
33 |
objects that are persistent, making changes to the object over time.
|
|
|
34 |
See \link{ReferenceClasses} and Chapter 9 of the reference for the
|
|
|
35 |
choice between these and S4 classes.
|
|
|
36 |
}
|
|
|
37 |
|
|
|
38 |
\section{Defining Classes}{
|
|
|
39 |
All objects in \R belong to a class; ordinary vectors and other basic
|
|
|
40 |
objects are built-in (\link{builtin-class}).
|
|
|
41 |
A new class is defined in terms of the named \emph{slots} that is has
|
|
|
42 |
and/or in terms of existing classes that it inherits from, or
|
|
|
43 |
\emph{contains} (discussed in \sQuote{Class Inheritance} below).
|
|
|
44 |
A call to \code{\link{setClass}()} names a new class and uses the corresponding arguments to
|
|
|
45 |
define it.
|
|
|
46 |
|
|
|
47 |
For example, suppose we want a class of objects to represent a
|
|
|
48 |
collection of positions, perhaps from GPS readings.
|
|
|
49 |
A natural way to think of these in \R would have vectors of numeric values for
|
|
|
50 |
latitude, longitude and altitude.
|
|
|
51 |
A class with three corresponding slots could be defined by:
|
|
|
52 |
|
|
|
53 |
\code{
|
|
|
54 |
Pos <- setClass("Pos", slots = c(latitude = "numeric",
|
|
|
55 |
longitude = "numeric", altitude = "numeric"))
|
|
|
56 |
}
|
|
|
57 |
|
|
|
58 |
The value returned is a function, typically assigned as here with the
|
|
|
59 |
name of the class. Calling this function returns an object from the
|
|
|
60 |
class; its arguments are named with the slot names.
|
|
|
61 |
If a function in the class had read the corresponding data, perhaps
|
|
|
62 |
from a CSV file or from a data base, it could return an object from
|
|
|
63 |
the class by:
|
|
|
64 |
|
|
|
65 |
\code{Pos(latitude = x, longitude = y, altitude = z)}
|
|
|
66 |
|
|
|
67 |
The slots are accessed by the
|
|
|
68 |
\code{\link{@}} operator; for example, if \code{g} is an object from
|
|
|
69 |
the class, \code{g@latitude}.
|
|
|
70 |
|
|
|
71 |
In addition to returning a generator function the call to
|
|
|
72 |
\code{\link{setClass}()} assigns a definition of the class in a
|
|
|
73 |
special metadata object in the package's namespace.
|
|
|
74 |
When the package is loaded into an \R session, the class definition is
|
|
|
75 |
added to a table of known classes.
|
|
|
76 |
|
|
|
77 |
To make the class and the generating function publicly available, the
|
|
|
78 |
package should include \code{POS} in \code{exportClasses()} and
|
|
|
79 |
\code{export()} directives in its \code{NAMESPACE} file:
|
|
|
80 |
|
|
|
81 |
\code{exportClasses(Pos); export(Pos)}
|
|
|
82 |
}
|
|
|
83 |
|
|
|
84 |
\section{Defining Methods}{
|
|
|
85 |
Defining methods for an \R function makes that function
|
|
|
86 |
\emph{generic}.
|
|
|
87 |
Instead of a call to the function always being carried out by the same
|
|
|
88 |
method, there will be several alternatives.
|
|
|
89 |
These are selected by matching the classes of the arguments in the call to a
|
|
|
90 |
table in the generic function, indexed by classes for one or more formal arguments to the
|
|
|
91 |
function, known as the \emph{signatures} for the methods.
|
|
|
92 |
|
|
|
93 |
|
|
|
94 |
A method definition then specifies three things: the name of the
|
|
|
95 |
function, the signature and the method definition itself.
|
|
|
96 |
The definition must be a function with the same formal arguments as
|
|
|
97 |
the generic.
|
|
|
98 |
|
|
|
99 |
For example, a method to make a plot of an object from class
|
|
|
100 |
\code{"Pos"} could be defined by:
|
|
|
101 |
|
|
|
102 |
\code{setMethod("plot", c("Pos", "missing"), function(x, y, ...) \{
|
|
|
103 |
plotPos(x, y) \})}
|
|
|
104 |
|
|
|
105 |
This method will match a call to \code{\link{plot}()} if the first
|
|
|
106 |
argument is from class \code{"Pos"} or a subclass of that.
|
|
|
107 |
The second argument must be missing; only a missing argument matches
|
|
|
108 |
that class in the signature.
|
|
|
109 |
Any object will match class \code{"ANY"} in the corresponding position
|
|
|
110 |
of the signature.
|
|
|
111 |
}
|
|
|
112 |
|
|
|
113 |
\section{Class Inheritance}{
|
|
|
114 |
|
|
|
115 |
A class may inherit all the slots and methods of one or more existing
|
|
|
116 |
classes by specifying the names of the inherited classes in the \code{contains =} argument to
|
|
|
117 |
\code{\link{setClass}()}.
|
|
|
118 |
|
| 71548 |
jmc |
119 |
To define a class that extends class \code{"Pos"} to a class
|
| 71366 |
jmc |
120 |
\code{"GPS"} with a slot for the observation times:
|
|
|
121 |
|
|
|
122 |
\code{GPS <- setClass("GPS", slots = c(time = "POSIXt"), contains = "Pos")}
|
|
|
123 |
|
|
|
124 |
The inherited classes may be S4 classes, S3
|
|
|
125 |
classes or basic data types.
|
|
|
126 |
S3 classes need to be identified as such by a call to
|
|
|
127 |
\code{\link{setOldClass}()}; most S3 classes in the base package and
|
|
|
128 |
many in the other built-in packages are already declared, as is
|
|
|
129 |
\code{"POSIXt"}.
|
|
|
130 |
If it had not been, the application package should contain:
|
|
|
131 |
|
|
|
132 |
\code{setOldClass("POSIXt")}
|
|
|
133 |
|
|
|
134 |
Inheriting from one of the \R types is special. Objects from the new
|
|
|
135 |
class will have the same type. A class
|
|
|
136 |
\code{Currency} that contains numeric data plus a slot \code{"unit"}
|
|
|
137 |
would be created by
|
|
|
138 |
|
|
|
139 |
\code{Currency <- setClass("Currency", slots = c(unit = "character"),
|
|
|
140 |
contains = "numeric")}
|
|
|
141 |
|
|
|
142 |
Objects created from this class will have type \code{"numeric"} and
|
|
|
143 |
inherit all the builtin arithmetic and other computations for that
|
|
|
144 |
type.
|
|
|
145 |
Classes can only inherit from at most one such type; if the class does
|
|
|
146 |
not inherit from a type, objects from the class will have type
|
|
|
147 |
\code{"S4"}.
|
|
|
148 |
|
|
|
149 |
}
|
|
|
150 |
|
|
|
151 |
|
|
|
152 |
\references{
|
| 88585 |
hornik |
153 |
\bibshow{R:Chambers:2016}
|
|
|
154 |
(Chapters 9 and 10.)
|
| 71366 |
jmc |
155 |
}
|
|
|
156 |
|