as {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)

as(object, Class) <- value

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

Arguments

object Any object.
Class The name of the class to which object should be coerced.
strict A 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 A 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.

Summary of Functions

as:
Returns the version of this object coerced to be the given Class.

If the corresponding is relation is true, it will be used. In particular, if the relation has a coerce method, the method will be invoked on object.

If the is relation is FALSE, and coerceFlag is TRUE, the coerce function will be called (which will throw an error if there is no valid way to coerce the two objects). Otherwise, NULL is returned.

Coerce methods are pre-defined for basic classes (including all the types of vectors, functions and a few others). The object asFunctions contains the list of such pre-defined relations: names(asFunctions) gives the names of all the classes.

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

coerce:
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:
The function supplied as the third argument is to be called to implement as(x, to) when x has class from. Need we add that the function should return a suitable object with class to.

How Functions 'as' and 'setAs' Work

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 a 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 desribed 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.

The Function 'as' Used in Replacements

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.

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

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 and ongoing development, see the web page http://developer.r-project.org/methodsPackage.html and the pointers from that page.

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")




[Package Contents]