as {methods} | R Documentation |
These functions manage the relations that allow coercing an object to a given class.
as(object, Class, strict=TRUE, ext) as(object, Class) <- value setAs(from, to, def, replace, where = topenv(parent.frame()))
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 (often 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 def performs coercion.
(In the case of the coerce function these are objects from
the classes, not the names of the classes, but you're not expected
to call coerce directly.) |
def |
function of one argument. It will get an object from
class from and had better return an object of class
to . (If you want to save setAs a little work, make
the name of the argument from , but don't worry about it,
setAs will do the conversion.) |
replace |
if supplied, the function to use as a replacement method. |
where |
the position or environment in which to store the
resulting method for coerce . |
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.
|
as
:Class
.
If the corresponding is(object, Class)
relation is true, it
will be used.
In particular, if the relation has a coerce method, the method
will be invoked on object
. However, if the object's
class extends Class
in a simple way (e.g, by including
the superclass in the definition, then the actual coercion will
be done only if strict
is TRUE
(non-strict
coercion, is used in passing objects to methods).
Coerce methods are pre-defined 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.
coerce
:from
to be of the same class as to
.
Not a function you should usually call explicitly. The function
setAs
creates methods for coerce
for the
as
function to use.
setAs
:as(x, to)
when x
has class from
.
Need we add that the function should return a suitable object with
class to
.
The function as
contrives to turn object
into an object
with class Class
. In doing so, it uses information about
classes and methods, but in a somewhat special way. Keep in mind
that 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 (see setClass
and setIs
).
Because inheritance is a powerful assertion, it should be used
sparingly (otherwise your computations may produce unexpected, and
perhaps incorrect, results). But objects can also be converted
explicitly, by calling as
, and that conversion is designed to
use any inheritance information, as well as explicit methods.
As a first step in conversion, the as
function determines
whether is(object, Class)
is TRUE
. This can be the case
either because the class definition of object
includes
Class
as a “super class” (directly or indirectly), or because
a call to setIs
established the relationship.
Either way, the inheritance relation defines a method to coerce
object
to Class
. In the most common case, the method
is just to extract from object
the slots needed for
Class
, but it's also possible to specify a method explicitly in
a setIs
call.
So, if inheritance applies, the as
function calls the
appropriate method. If inheritance does not apply, and
coerceFlag
is FALSE
, NULL
is returned.
By default, coerceFlag
is TRUE
. In this case the
as
function goes on to look for a method for the function
coerce
for the signature c(from = class(object), to =
Class)
.
Method selection is used in the as
function in two special
ways.
First, inheritance is
applied for the argument from
but 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).
Second, the function tries to use inheritance information to convert
the object indirectly, by first converting it to an inherited class.
It does this by examining the classes that the from
class
extends, to see if any of them has an explicit conversion method.
Suppose class "by"
does: Then the as
function
implicitly computes as(as(object, "by"), 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 only argument: The default for the
second argument is provided so the method can know the intended
to
class.
The function coerce
exists almost entirely as a repository for such methods, to be
selected as described above by the as
function.
In fact, it
would usually be a bad idea to call coerce
directly, since then
you would get inheritance on the to
argument; as mentioned,
this is not likely to be what you want.
When as
appears on the left of an assignment, the intuitive
meaning is “Replace the part of object
that was inherited from
Class
by the value
on the right of the assignment.”
This usually has a straightforward interpretation, but you can control explicitly what happens, and sometimes you should to avoid possible corruption of objects.
When object
inherits from Class
in the usual way, by
including the slots of Class
, the default as
method is
to set the corresponding slots in object
to those in
value
.
The default computation may be reasonable, but usually only if all
other slots in object
are unrelated to the slots being
changed. Often, however, this is not the case. The class of
object
may have extended Class
with a new slot whose
value depends on the inherited slots. In this case, you may want to
define a method for replacing the inherited information that
recomputes all the dependent information. Or, you may just want to
prohibit replacing the inherited information directly .
The way to control such replacements is through the replace
argument to function setIs
. This argument is a method that
function as
calls when used for replacement. It can do
whatever you like, including calling stop
if you want to
prohibit replacements. It should return a modified object with the
same class as the object
argument to as
.
In R, you can also explicitly supply a replacement method, even in the
case that inheritance does not apply, through the replace
argument to setAs
. It works essentially the same way, but in
this case by constructing a method for "coerce<-"
. (Replace
methods for coercion without inheritance are not in the original
description and so may not be compatible with S-Plus, at least not
yet.)
When inheritance does apply, coerce and replace methods can be
specified through either setIs
or setAs
; the effect is
essentially the same.
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")
.
The R package methods implements, with a few exceptions, the programming interface for classes and methods in the book Programming with Data (John M. Chambers, Springer, 1998), in particular sections 1.6, 2.7, 2.8, and chapters 7 and 8.
While the programming interface for the methods package follows
the reference, the R software is an original implementation, so
details in the reference that reflect the S4 implementation may appear
differently in R. Also, there are extensions to the programming
interface developed more recently than the reference. For a
discussion of details see ?Methods
and the links from that documentation.
If you think of using try(as(x, cl))
, consider
canCoerce(x, cl)
instead.
## 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")