Top Banner

of 138

Object-Oriented in R

Apr 14, 2018

Download

Documents

daselknam
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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")