0

Can anyone explain this to me (R 3.0.1)? Why do elements of a vector not have the same class as the vector itself? Somehow the units attribute does not carry down to the elements. Many thanks in advance.

> x <- as.difftime( 0.5, units='mins' )
> print(class(x))
[1] "difftime"

> y <- as.difftime( c(0.5,1,2), units='mins' )
> print(class(y))
[1] "difftime"

> for (z in y) print(class(z))
[1] "numeric"
[1] "numeric"
[1] "numeric"
Robert Almgren
  • 781
  • 1
  • 6
  • 4

2 Answers2

2

There is a [.difftime version of the [function but no [[.difftime version of [[

> `[.difftime`
function (x, ..., drop = TRUE) 
{
    cl <- oldClass(x)
    class(x) <- NULL
    val <- NextMethod("[")
    class(val) <- cl
    attr(val, "units") <- attr(x, "units")
    val
}
<bytecode: 0x1053916e0>
<environment: namespace:base>

So the for function is pulling items from the y-object with [[ and it is loosing its attributes. This would let you get what you expected to see:

> for(i in seq_along(y) ){print(y[i])}
Time difference of 0.5 mins
Time difference of 1 mins
Time difference of 2 mins
> for(i in seq_along(y) ){print(class(y[i]))}
[1] "difftime"
[1] "difftime"
[1] "difftime"
IRTFM
  • 258,963
  • 21
  • 364
  • 487
0

The class of an object does not have to be the same as the storage mode of the elements of that object. From the help page for class:

Many R objects have a class attribute, a character vector giving the names of the classes from which the object inherits. If the object does not have a class attribute, it has an implicit class, "matrix", "array" or the result of mode(x) (except that integer vectors have implicit class "integer").

So if you do:

y <- as.difftime( c(0.5,1,2), units='mins' )

# 'typeof' determines the (R internal) type or storage mode of any object
typeof( y )
# [1] "double"

# And mode: Modes have the same set of names as types (see typeof) except that
# types "integer" and "double" are returned as "numeric".
mode( y )
# [1] "numeric"

class is a programming construct, which allows you to do something like this:

# Integer vector
x <- 1:5
#  Set the class with 'class<-'
class(x) <- "foo"

#  Which is correctly returned by 'class'
class(x)
# [1] "foo"

#  But our elements are still integers...
typeof(x)
[1] "integer"
Simon O'Hanlon
  • 58,647
  • 14
  • 142
  • 184