Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is.object and the S3 class system

Tags:

oop

r

r-s3

r-s4

Using the class function allows us to determine the class of an object:

> x = 5
> class(x)
[1] "numeric"

I also understand that we can use the is.object command to determine if an object has a class. However some object types are implicit, that is

> is.object(x)
[1] FALSE

Would it be correct to state that all variables in R are objects and is.object is a test for non-implicit classes only?

Also, how do types fit into this. Naively, I thought that the following piece of code would produce an error:

> x = 5
> class(x) = "fake"
> x = X + 1
> x + 1
[1] 6
attr(,"class")
[1] "fake"

But x still has type "double", still everything still works. Can types be thought of as a superclass that all other objects inherit from?

like image 662
csgillespie Avatar asked Jan 18 '11 14:01

csgillespie


2 Answers

typeof returns the type of internal C representation, and it is not used for method dispatch. So strictly speaking you can not think of types as "superclasses".

There are instead basic classes (numeric, character, list, function etc) which roughly correspond to the names returned by typeof, but not always (for example type double is of class numeric, special and closure are of class function, and class data.frame is of type list!).

With S3 and S4 systems you can build non trivial classes using basic classes (but not necessary extending one of those!! example: setClass("foo", list(a="numeric",b="character") does not extend any of the basic classes).

For objects from these basic classes is.object returns FALSE. As its documentation says, this function provides a very fast way to check if the object is of user build S3 or S4 class (i.e. not one of basic classes).

After casting x as "fake" your object is formally not of "numeric" class:

is(x, "numeric")
#FALSE

but it is interpretable as basic "numeric" object:

is.numeric(x)
#TRUE

And this is why + works here. So, internally, as @Richie already said the default method interprets x as of numeric basic class.

This conceptual mess is because of S3 informal treatment of classes. Use S4 instead.


correspondence between typeof(.) and basic class(.):

                              typeof(.)  class(.)
NULL                          "NULL"     "NULL"
1                             "double"   "numeric"
1:1                           "integer"  "integer"
1i                            "complex"  "complex"
list(1)                       "list"     "list"
data.frame(x=1)               "list"     "data.frame"
pairlist(pi)                  "pairlist" "pairlist"
c                             "special"  "function"
lm                            "closure"  "function"
formals(lm)[[1]]              "symbol"   "name"
formals(lm)[[2]]              "symbol"   "name"
y~x                           "language" "formula"
expression((1))[[1]]          "language" "("
(y~x)[[1]]                    "symbol"   "name"
expression(x <- pi)[[1]][[1]] "symbol"   "name"
like image 92
VitoshKa Avatar answered Sep 22 '22 02:09

VitoshKa


A partial answer to the first question is found in Chapter 2 of the R language defninition

R does not provide direct access to the computer’s memory but rather provides a number of specialized data structures we will refer to as objects. These objects are referred to through symbols or variables. In R, however, the symbols are themselves objects and can be manipulated in the same way as any other object.

So, yes, all variables are objects.

is.object seems to be more or less equivalent to function(x) !is.null(attr(x, "class")) but I'm willing to be proved wrong on that.

As for the second question, I think this is what happens: Since x has class "fake", R looks for a method +.fake in the addition but when it doesn't find one, it resorts to the default method. That default method is based upon underlying C code, which uses typeof(x) (or a C equivalent) to determine what should be done. In this case the type of x is "integer".

like image 39
Richie Cotton Avatar answered Sep 23 '22 02:09

Richie Cotton