The language R confuses me. Entities have modes and classes, but even this is insufficient to fully describe the entity.
This answer says
In R every 'object' has a mode and a class.
So I did these experiments:
> class(3) [1] "numeric" > mode(3) [1] "numeric" > typeof(3) [1] "double"
Fair enough so far, but then I passed in a vector instead:
> mode(c(1,2)) [1] "numeric" > class(c(1,2)) [1] "numeric" > typeof(c(1,2)) [1] "double"
That doesn't make sense. Surely a vector of integers should have a different class, or different mode, than a single integer? My questions are:
Update: Apparently, a literal 3 is just a vector of length 1. There are no scalars. OK But... I tried mode("string")
and got "character"
, leading me to think that a string was a vector of characters. But if that was true, then this should be true, but it's not! c('h','i') == "hi"
typeof() gives the "type" of object from R's point of view, whilst mode() gives the "type" of object from the point of view of Becker, Chambers & Wilks (1988). The latter may be more compatible with other S implementations according to the R Language Definition manual.
mode (almost the same thing) is basically the most complex datatype that an R object can hold as one of its values; whereas. class is an object's object-oriented classification according to the R class hierarchy.
R has six basic ('atomic') vector types: logical, integer, real, complex, string (or character) and raw. The modes and storage modes for the different vector types are listed in the following table.
The mode is the value that has highest number of occurrences in a set of data. Unike mean and median, mode can have both numeric and character data. R does not have a standard in-built function to calculate mode. So we create a user function to calculate mode of a data set in R.
I agree that the type system in R is rather weird. The reason for it being that way is that it has evolved over (a long) time...
Note that you missed one more type-like function, storage.mode
, and one more class-like function, oldClass
.
So, mode
and storage.mode
are the old-style types (where storage.mode
is more accurate), and typeof
is the newer, even more accurate version.
mode(3L) # numeric storage.mode(3L) # integer storage.mode(`identical`) # function storage.mode(`if`) # function typeof(`identical`) # closure typeof(`if`) # special
Then class
is a whole different story. class
is mostly just the class
attribute of an object (that's exactly what oldClass
returns). But when the class attribute is not set, the class
function makes up a class from the object type and the dim attribute.
oldClass(3L) # NULL class(3L) # integer class(structure(3L, dim=1)) # array class(structure(3L, dim=c(1,1))) # matrix class(list()) # list class(structure(list(1), dim=1)) # array class(structure(list(1), dim=c(1,1))) # matrix class(structure(list(1), dim=1, class='foo')) # foo
Finally, the class can return more than one string, but only if the class attribute is like that. The first string value is then kind of the main class, and the following ones are what it inherits from. The made-up classes are always of length 1.
# Here "A" inherits from "B", which inherits from "C" class(structure(1, class=LETTERS[1:3])) # "A" "B" "C" # an ordered factor: class(ordered(3:1)) # "ordered" "factor"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With