When you call a function with an argument of the wrong type, R will try to coerce values to a different type so that the function will work. There are two types of coercion that occur automatically in R: coercion with formal objects and coercion with built-in types.
With generic functions, R will look for a suitable method. If no exact match exists, then R will search for a coercion method that converts the object to a type for which a suitable method does exist. (The method for creating coercion functions is described in Creating Coercion Methods.)
Additionally, R will automatically convert between built-in object
types when appropriate. R will convert from more specific types to more
general types. For example, suppose that you define a vector x
as follows:
> x <- c(1, 2, 3, 4, 5) > x [1] 1 2 3 4 5 > typeof(x) [1] "double" > class(x) [1] "numeric"
Let’s change the second element of the vector to the word “hat.” R
will change the object class to character
and change all the elements in the
vector to char
:
> x[2] <- "hat" > x [1] "1" "hat" "3" "4" "5" > typeof(x) [1] "character" > class(x) [1] "character"
Here is an overview of the coercion rules:
Logical values are converted to numbers: TRUE
is converted to 1
and FALSE
to 0
.
Values are converted to the simplest type required to represent all information.
The ordering is roughly logical < integer < numeric < complex < character < list.
Objects of type raw
are not
converted to other types.
Object attributes are dropped when an object is coerced from one type to another.
You can inhibit coercion when passing arguments to functions by
using the AsIs
function (or,
equivalently, the I
function). For more
information, see the help file for AsIs
.
Many newcomers to R find coercion nonintuitive. Strongly typed languages (like Java) will raise exceptions when the object passed to a function is the wrong type but will not try to convert the object to a compatible type. As John Chambers (who developed the S language) describes:
In the early coding, there was a tendency to make as many cases “work” as possible. In the later, more formal, stages the conclusion was that converting richer types to simpler automatically in all situations would lead to confusing, and therefore untrustworthy, results.[16]
In practice, I rarely encounter situations where values are coerced in undesirable ways. Usually, I use R with numeric vectors that are all the same type, so coercion simply doesn’t apply.