setMethod              package:methods              R Documentation

Create and Save a Method

Description:

     Create and save a formal method for a given function and list of
     classes.

Usage:

     setMethod(f, signature=character(), definition,
               where = topenv(parent.frame()),
               valueClass = NULL, sealed = FALSE)

     removeMethod(f, signature, where)

Arguments:

       f: A generic function or the character-string name of the
          function. 

signature: A match of formal argument names for 'f' with the
          character-string names of corresponding classes.  See the
          details below; however, if the signature is not trivial, you
          should use 'method.skeleton' to generate a valid call to
          'setMethod'.

definition: A function definition, which will become the method called
          when the arguments in a call to 'f' match the classes in
          'signature', directly or through inheritance. 

   where: the environment in which to store the definition of the
          method. For 'setMethod', it is recommended to omit this
          argument and to include the call in source code that is
          evaluated at the top level; that is, either in an R session
          by something equivalent to a call to 'source', or as part of
          the R source code for a package.

          For 'removeMethod', the default is the location of the
          (first) instance of the method for this signature.

valueClass: Obsolete and unused, but see the same argument for
          'setGeneric'. 

  sealed: If 'TRUE', the method so defined cannot be redefined by
          another call to 'setMethod' (although it can be removed and
          then re-assigned).

Details:

     The call to 'setMethod' stores the supplied method definition  in
     the metadata table for this generic function in the environment,
     typically the global environment or the name space of a package.
     In the case of a package, the table object becomes part of the
     name space or environment of the package. When the package is
     loaded into a later session, the methods will be merged into the
     table of methods in the corresponding generic function object.

     Generic functions are referenced by the combination of the
     function name and the package name; for example, the function
     '"show"' from the package '"methods"'. Metadata for methods is
     identified by the two strings; in particular, the generic function
     object itself has slots containing its name and its package name.
     The package name of a generic is set according to the package from
     which it originally comes; in particular, and frequently, the
     package where a non-generic version of the function originated.
     For example, generic functions for all the functions in package
     'base' will have '"base"' as the package name, although none of
     them is an S4 generic on that package.

     Multiple packages can have methods for the same generic function;
     that is, for the same combination of generic function name and
     package name. Even though the methods are stored in separate
     tables in separate environments, loading the corresponding
     packages adds the methods to the table in the generic function
     itself, for the duration of the session.

     The class names in the signature can be any formal class,
     including basic classes such as '"numeric"', '"character"', and
     '"matrix"'.  Two additional special class names can appear:
     '"ANY"', meaning that this argument can have any class at all; and
     '"missing"', meaning that this argument _must not_ appear in the
     call in order to match this signature.  Don't confuse these two: 
     if an argument isn't mentioned in a signature, it corresponds
     implicitly to class '"ANY"', not to '"missing"'.  See the example
     below.  Old-style ('S3') classes can also be used, if you need
     compatibility with these, but you should definitely declare these
     classes by calling 'setOldClass' if you want S3-style inheritance
     to work.

     Method definitions can have default expressions for arguments, but
     a current limitation is that the generic function must have _some_
     default expression for the same argument in order for the method's
     defaults to be used. If so, and if the corresponding argument is
     missing in the call to the generic function, the default
     expression in the method is used.  If the method definition has no
     default for the argument, then the expression supplied in the
     definition of the generic function itself is used, but note that
     this expression will be evaluated using the enclosing environment
     of the method, not of the generic function. Note also that
     specifying class '"missing"' in the signature does not require any
     default expressions, and method selection does not evaluate
     default expressions. All actual (non-missing) arguments in the
     signature of the generic function will be evaluated when a method
     is selected-when the call to 'standardGeneric(f)' occurs.

     It is possible to have some differences between the formal
     arguments to a method supplied to 'setMethod' and those of the
     generic. Roughly, if the generic has ... as one of its arguments,
     then the method may have extra formal arguments, which will be
     matched from the arguments matching ... in the call to 'f'.  (What
     actually happens is that a local function is created inside the
     method, with the modified formal arguments, and the method is
     re-defined to call that local function.)

     Method dispatch tries to match the class of the actual arguments
     in a call to the available methods collected for 'f'.  If there is
     a method defined for the exact same classes as in this call, that
     method is used.  Otherwise, all possible signatures are considered
     corresponding to the actual classes or to superclasses of the
     actual classes (including '"ANY"'). The method having the least
     distance from the actual classes is chosen; if more than one
     method has minimal distance, one is chosen (the lexicographically
     first in terms of superclasses) but a warning is issued. All
     inherited methods chosen are stored in another table, so that the
     inheritance calculations only need to be done once per session per
     sequence of actual classes. See Methods for more details.

     The function 'removeMethod' removes the specified method from the
     metadata table in the corresponding environment. It's not a
     function that is used much, since one normally wants to redefine a
     method rather than leave no definition.

Value:

     These functions exist for their side-effect, in setting or
     removing a method in the object defining methods for the specified
     generic.

     The value returned by 'removeMethod' is 'TRUE' if a method was
     found to be removed.

References:

     Chambers, John M. (2008) _Software for Data Analysis: Programming
     with R_ Springer.  (For the R version.)

     Chambers, John M. (1998) _Programming with Data_ Springer (For the
     original S4 version.)

See Also:

     'method.skeleton', which is the recommended way to generate a
     skeleton of the call to 'setMethod', with the correct formal
     arguments and other details.

     Methods and the links there for a general discussion,
     'dotsMethods' for methods that dispatch on "...", and 'setGeneric'
     for generic functions.

Examples:

     require(graphics)
     ## methods for plotting track objects (see the example for setClass)
     ##
     ## First, with only one object as argument:
     setMethod("plot", signature(x="track", y="missing"),
       function(x,  y, ...) plot(slot(x, "x"), slot(x, "y"), ...)
     )
     ## Second, plot the data from the track on the y-axis against anything
     ## as the x data.
     setMethod("plot", signature(y = "track"),
      function(x, y, ...) plot(x, slot(y, "y"), ...)
     )
     ## and similarly with the track on the x-axis (using the short form of
     ## specification for signatures)
     setMethod("plot", "track",
      function(x, y, ...) plot(slot(x, "y"), y,  ...)
     )
     t1 <- new("track", x=1:20, y=(1:20)^2)
     tc1 <- new("trackCurve", t1)
     slot(tc1, "smooth") <- smooth.spline(slot(tc1, "x"), slot(tc1, "y"))$y #$
     plot(t1)
     plot(qnorm(ppoints(20)), t1)
     ## An example of inherited methods, and of conforming method arguments
     ## (note the dotCurve argument in the method, which will be pulled out
     ## of ... in the generic.
     setMethod("plot", c("trackCurve", "missing"),
     function(x, y, dotCurve = FALSE, ...) {
       plot(as(x, "track"))
       if(length(slot(x, "smooth") > 0))
         lines(slot(x, "x"), slot(x, "smooth"),
              lty = if(dotCurve) 2 else 1)
       }
     )
     ## the plot of tc1 alone has an added curve; other uses of tc1
     ## are treated as if it were a "track" object.
     plot(tc1, dotCurve = TRUE)
     plot(qnorm(ppoints(20)), tc1)

     ## defining methods for a special function.
     ## Although "[" and "length" are not ordinary functions
     ## methods can be defined for them.
     setMethod("[", "track",
       function(x, i, j, ..., drop) {
         x@x <- x@x[i]; x@y <- x@y[i]
         x
       })
     plot(t1[1:15])

     setMethod("length", "track", function(x)length(x@y))
     length(t1)

     ## methods can be defined for missing arguments as well
     setGeneric("summary") ## make the function into a generic

     ## A method for summary()
     ## The method definition can include the arguments, but
     ## if they're omitted, class "missing" is assumed.

     setMethod("summary", "missing", function() "<No Object>")

