So far, we’ve run some calculations and assigned some variables. In this chapter, we’ll find out ways to examine the properties of those variables and to manipulate the user workspace that contains them.
After reading this chapter, you should:
All variables in R have a class, which tells you what kinds of variables they are. For example, most numbers have class numeric
(see the next section for the other types), and logical values have class logical
. Actually, being picky about it, vectors of numbers are numeric
and vectors of logical values are logical
, since R has no scalar types. The “smallest” data type in R is a vector.
You can find out what the class of a variable is using class(my_variable)
:
class(
c(
TRUE
,
FALSE
))
## [1] "logical"
It’s worth being aware that as well as a class, all variables also have an internal storage type (accessed via typeof
), a mode (see mode
), and a storage mode (storage.mode
). If this sounds complicated, don’t worry! Types, modes, and storage modes mostly exist for legacy purposes, so in practice you should only ever need to use an object’s class
(at least until you join the R Core Team). Appendix A has a reference table showing the relationships between class, type, and (storage) mode for many sorts of variables. Don’t bother memorizing it, and don’t worry if you don’t recognize some of the classes. It is simply worth browsing the table to see which things are related to which other things.
From now on, to make things easier, I’m going to use “class” and “type” synonymously (except where noted).
All the variables that we created in the previous chapter were numbers, but R contains three different classes of numeric variable: numeric
for floating point values; integer
for, ahem, integers; and complex
for complex numbers. We can tell which is which by examining the class
of the variable:
class(
sqrt(
1
:10
))
## [1] "numeric"
class(
3
+
1
i)
#"i" creates imaginary components of complex numbers
## [1] "complex"
class(
1
)
#although this is a whole number, it has class numeric
## [1] "numeric"
class(
1
L)
#add a suffix of "L" to make the number an integer
## [1] "integer"
class(
0.5
:4.5
)
#the colon operator returns a value that is numeric...
## [1] "numeric"
class(
1
:5
)
#unless all its values are whole numbers
## [1] "integer"
Note that as of the time of writing, all floating point numbers are 32-bit numbers (“double precision”), even when installed on a 64-bit operating system, and 16-bit (“single precision”) numbers don’t exist.
Typing .Machine
gives you some information about the properties of R’s numbers. Although the values, in theory, can change from machine to machine, for most builds, most of the values are the same. Many of the values returned by .Machine
need never concern you. It’s worth knowing that the largest floating point number that R can represent at full precision is about 1.8e308
. This is big enough for everyday purposes, but a lot smaller than infinity! The smallest positive number that can be represented is 2.2e-308
. Integers can take values up to 2 ^ 31 - 1
, which is a little over two billion, (or down to -2 ^ 31 + 1
).[8]
The only other value of much interest is ε, the smallest positive floating point number such that |ε + 1| != 1
. That’s a fancy way of saying how close two numbers can be so that R knows that they are different. It’s about 2.2e-16
. This value is used by all.equal
when you compare two numeric vectors.
In fact, all of this is even easier than you think, since it is perfectly possible to get away with not (knowingly) using integers. R is designed so that anywhere an integer is needed—indexing a vector, for example—a floating point “numeric” number can be used just as well.
In addition to the three numeric classes and the logical class that we’ve seen already, there are three more classes of vectors: character
for storing text, factor
s for storing categorical data, and the rarer raw
for storing binary data.
In this next example, we create a character vector using the c
operator, just like we did for numeric vectors. The class of a character vector is character
:
class(
c(
"she"
,
"sells"
,
"seashells"
,
"on"
,
"the"
,
"sea"
,
"shore"
))
## [1] "character"
Note that unlike some languages, R doesn’t distinguish between whole strings and individual characters—a string containing one character is treated the same as any other string. Unlike with some other lower-level languages, you don’t need to worry about terminating your strings with a null character (