by Karl-Kuno Kunze
This post shows some of the peculiarities of R. The brute force way to assign classes to less structured objecs
- is not the only way
- may not be appropriate.
Mechanism 1
Usually, being member of a certain class is expressed by an attribute called ‘class’. So the following three expressions are somewhat equivalent:
1 2 3 4 5 6 7 8 9 10 |
myD1 <- as.Date("1970-01-02") myD2 <- 1 class(myD2) <- "Date" myD3 <- 1 attr(myD3, "class") <- "Date" myD1; myD2; myD3 |
1 |
## [1] "1970-01-02" |
1 |
## [1] "1970-01-02" |
1 |
## [1] "1970-01-02" |
You may check with the attributes() and identical() statements, that they are really identical:
1 2 |
attributes(myD1); attributes(myD2) |
1 2 |
## $class ## [1] "Date" |
1 2 |
## $class ## [1] "Date" |
1 2 |
identical(myD1, myD2) |
1 |
## [1] TRUE |
Taking the class away, either through a casting function, through unclass(), or through setting the attribute to NULL, is shown here:
1 2 3 4 5 6 7 8 |
myD1 <- as.numeric(myD1) myD2 <- unclass(myD2) attr(myD3, "class") <- NULL myD1; myD2; myD3 |
1 |
## [1] 1 |
1 |
## [1] 1 |
1 |
## [1] 1 |
All three elements are plain vectors now with one element.
Mechanism 2
However, look at this:
1 2 3 |
myM <- matrix(c(1:4), nrow= 2) class(myM) |
1 |
## [1] "matrix" |
1 2 3 |
myM <- unclass(myM) class(myM) |
1 |
## [1] "matrix" |
1 2 |
myM |
1 2 3 |
## [,1] [,2] ## [1,] 1 3 ## [2,] 2 4 |
What is going on here? Although we took away the class, it still remembers its class ‘matrix’.
Let’s have a closer look at the attributes:
1 2 |
attributes(myM) |
1 2 |
## $dim ## [1] 2 2 |
In fact, there is no attribute ‘class’, but rather an attribute called ‘dim’. Let’s use this for some manipulations. First we rip off the attribute:
1 2 3 |
attr(myM, "dim") <- NULL class(myM) |
1 |
## [1] "integer" |
1 2 |
myM |
1 |
## [1] 1 2 3 4 |
Now we attach it again
1 2 3 |
attr(myM, "dim") <- c(2,2) class(myM) |
1 |
## [1] "matrix" |
1 2 |
myM |
1 2 3 |
## [,1] [,2] ## [1,] 1 3 ## [2,] 2 4 |
That is, the attribute ‘class’ is not the only attribute to eventually set a class. Even more, let us now set an attribute class to the value ‘Date’:
1 2 3 |
attr(myM, "class") <- "Date" myM |
1 |
## [1] "1970-01-02" "1970-01-03" "1970-01-04" "1970-01-05" |
1 2 |
attributes(myM) |
1 2 3 4 5 |
## $dim ## [1] 2 2 ## ## $class ## [1] "Date" |
So, if there is an attribute ‘class’ it overrides any secondary class affiliation