as                  package:methods                  R Documentation

Force an Object to Belong to a Class

Description:

     These functions manage the relations that allow coercing an object
     to a given class.

Usage:

     as(object, Class, strict=TRUE, ext)

     as(object, Class) <- value

     setAs(from, to, def, replace, where = topenv(parent.frame()))

Arguments:

  object: any R object.

   Class: the name of the class to which 'object' should be coerced. 

  strict: logical flag.  If 'TRUE', the returned object must be
          strictly from the target class (unless that class is a
          virtual class, in which case the object will be from the
          closest actual class, in particular the original object, if
          that class extends the virtual class directly).

          If 'strict = FALSE', any simple extension of the target class
          will be returned, without further change.  A simple extension
          is, roughly, one that just adds slots to an existing class.

   value: The value to use to modify 'object' (see the discussion
          below).  You should supply an object with class 'Class'; some
          coercion is done, but you're unwise to rely on it.

from, to: The classes between which the coerce methods 'def' and
          'replace' perform coercion. 

     def: function of one argument.  It will get an object from class
          'from' and had better return an object of class 'to'. The
          convention is that the name of the argument is 'from'; if
          another argument name is used, 'setAs' will attempt to
          substitute 'from'. 

 replace: if supplied, the function to use as a replacement method,
          when 'as' is used on the left of an assignment. Should be a
          function of two arguments, 'from, value', although 'setAs'
          will attempt to substitute if the arguments differ.

   where: the position or environment in which to store the resulting
          methods. For most applications, it is recommended to omit
          this argument and to include the call to 'setAs' 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.

     ext: the optional object defining how 'Class' is extended by the
          class of the object (as returned by 'possibleExtends'). This
          argument is used internally (to provide essential information
          for non-public classes), but you are unlikely to want to use
          it directly. 

Summary of Functions:


     'as': Returns the version of this object coerced to be the given
          'Class'.  When used in the replacement form on the left of an
          assignment, the portion of the object corresponding to
          'Class' is replaced by 'value'.

          The operation of 'as()' in either form depends on the
          definition of coerce methods.  Methods are defined
          automatically when the two classes are related by
          inheritance; that is, when one of the classes is a subclass
          of the other.  See the section on inheritance  below for
          details.

          Coerce methods are also predefined for basic classes
          (including all the types of vectors, functions and a few
          others). See 'showMethods(coerce)' for a list of these.

          Beyond these two sources of methods, further methods are
          defined by calls to the 'setAs' function.


     'setAs': Define methods for coercing an object of class 'from' to
          be of class 'to'; the 'def' argument provides for direct
          coercing and the 'replace' argument, if included, provides
          for replacement.  See the "How" section below for details.


     'coerce', 'coerce<-': Coerce 'from' to be of the same class as
          'to'.

          These functions should not be called explicitly.  The
          function 'setAs' creates methods for them for the 'as'
          function to use.


Inheritance and Coercion:

     Objects from one class can turn into objects from another class
     either automatically or by an explicit call to the 'as' function. 
     Automatic conversion is special, and comes from the designer of
     one class of objects asserting that this class extends another
     class.  The most common case is that one or more class names are
     supplied in the 'contains=' argument to 'setClass', in which case
     the new class extends each of the earlier classes (in the usual
     terminology, the earlier classes are _superclasses_ of the new
     class and it is a _subclass_ of each of them).

     This form of inheritance is called _simple_ inheritance in R. See
     'setClass' for details. Inheritance can also be defined explicitly
     by a call to 'setIs'. The two versions have slightly different
     implications for coerce methods. Simple inheritance implies that
     inherited slots behave identically in the subclass and the
     superclass. Whenever two classes are related by simple
     inheritance, corresponding coerce methods are defined for both
     direct and replacement use of 'as'. In the case of simple
     inheritance, these methods do the obvious computation:  they
     extract or replace the slots in the object that correspond to
     those in the superclass definition.

     The implicitly defined coerce methods may be overridden by a call
     to 'setAs'; note, however, that the implicit methods are defined
     for each subclass-superclass pair, so that you must override each
     of these explicitly, not rely on inheritance.

     When inheritance is defined by a call to 'setIs', the coerce
     methods are provided explicitly, not generated automatically.
     Inheritance will apply (to the 'from' argument, as described in 
     the section below). You could also supply methods via 'setAs' for
     non-inherited relationships, and now these also can be inherited.

     For further on the distinction between simple and explicit
     inheritance, see 'setIs'.

How Functions 'as' and 'setAs' Work:

     The function 'as'  turns 'object' into an object of class 'Class'.
      In doing so, it applies a "coerce method", using S4 classes and
     methods, but in a somewhat special way. Coerce methods are methods
     for the function 'coerce' or, in the replacement case the function
     '`coerce<-`'. These functions have two arguments in method
     signatures, 'from' and 'to', corresponding to the class of the
     object and the desired coerce class. These functions must not be
     called directly, but are used to store tables of methods for the
     use of 'as', directly and for replacements. In this section we
     will describe the direct case, but except where noted the
     replacement case works the same way, using '`coerce<-`' and the
     'replace' argument to 'setAs', rather than 'coerce' and the 'def'
     argument.

     Assuming the 'object' is not already of the desired class, 'as'
     first looks for a method in the table of methods for the function
     'coerce' for the signature 'c(from = class(object), to = Class)',
     in the same way method selection would do its initial lookup. To
     be precise, this means the table of both direct and inherited
     methods, but inheritance is used specially in this case (see
     below).

     If no method is found, 'as' looks for one. First, if either
     'Class' or 'class(object)' is a superclass of the other, the class
     definition will contain the information needed to construct a
     coerce method. In the usual case that the subclass contains the
     superclass (i.e., has all its slots), the method is constructed
     either by extracting or replacing the inherited slots. Non-simple
     extensions (the result of a call to 'setIs') will usually contain
     explicit methods, though possibly not for replacement. 

     If no subclass/superclass relationship provides a method, 'as'
     looks for an inherited method, but applying, inheritance for the
     argument 'from' only, not for the argument 'to' (if you think
     about it, you'll probably agree that you wouldn't want the result
     to be from some class other than the 'Class' specified). Thus,
     'selectMethod("coerce", sig, useInherited= c(from=TRUE, to=
     FALSE))' replicates the method selection used by 'as()'.

     In nearly all cases the method found in this way will be cached in
     the table of coerce methods (the exception being subclass
     relationships with a test, which are legal but discouraged). So
     the detailed calculations should be done only on the first
     occurrence of a coerce from 'class(object)' to 'Class'.

     With this explanation as background, the function 'setAs' does a
     fairly obvious computation:  It constructs and sets a method for
     the function 'coerce' with signature 'c(from, to)', using the
     'def' argument to define the body of the method.  The function
     supplied as 'def' can have one argument (interpreted as an object
     to be coerced) or two arguments (the 'from' object and the 'to'
     class).  Either way, 'setAs' constructs a function of two
     arguments, with the second defaulting to the name of the 'to'
     class.  The method will be called from 'as' with the object as the
     'from' argument and no 'to' argument, with the default for this
     argument being the name of the intended 'to' class, so the method
     can use this information in messages.

     The direct version of the 'as' function also has a 'strict='
     argument that defaults to 'TRUE'. Calls during the evaluation of
     methods for other functions will set this argument to 'FALSE'. The
     distinction is relevant when the object being coerced is from a
     simple subclass of the 'to' class; if 'strict=FALSE' in this case,
     nothing need be done. For most user-written coerce methods, when
     the two classes have no subclass/superclass, the 'strict='
     argument is irrelevant.

     The 'replace' argument to 'setAs' provides a method for
     '`coerce<-`'. As with all replacement methods, the last argument
     of the method must have the name 'value' for the object on the
     right of the assignment. As with the 'coerce' method, the first
     two arguments are 'from, to'; there is no 'strict=' option for the
     replace case.

     The function 'coerce' exists as a repository for such methods, to
     be selected as described above by the 'as' function.  Actually
     dispatching the methods using 'standardGeneric' could produce
     incorrect inherited methods, by using inheritance on the 'to'
     argument; as mentioned, this is not the logic used for 'as'. To
     prevent selecting and caching invalid methods, calls to 'coerce'
     are currently mapped into calls to 'as', with a warning message.

Basic Coercion Methods:

     Methods are pre-defined for coercing any object to one of the
     basic datatypes.  For example, 'as(x, "numeric")' uses the
     existing 'as.numeric' function.  These built-in methods can be
     listed by 'showMethods("coerce")'.

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:

     If you think of using 'try(as(x, cl))', consider 'canCoerce(x,
     cl)' instead.

Examples:

     ## using the definition of class "track" from Classes



     setAs("track", "numeric", function(from) from@y)

     t1 <- new("track", x=1:20, y=(1:20)^2)

     as(t1, "numeric")

     ## The next example shows:
     ##  1. A virtual class to define setAs for several classes at once.
     ##  2. as() using inherited information

     setClass("ca", representation(a = "character", id = "numeric"))

     setClass("cb", representation(b = "character", id = "numeric"))

     setClass("id")
     setIs("ca", "id")
     setIs("cb", "id")

     setAs("id", "numeric", function(from) from@id)

     CA <- new("ca", a = "A", id = 1)
     CB <- new("cb", b = "B", id = 2)

     setAs("cb", "ca", function(from, to )new(to, a=from@b, id = from@id))

     as(CB, "numeric")

