5 R Objects

5.1 Atomic Vector

An atomic vector is a simple vector of data. You can make an atomic vector by grouping some values of data together with c, and test whether an object is an atomic vector with is.vector:

die <- c(1,2,3,4,5,6)
die
## [1] 1 2 3 4 5 6
is.vector(die)
## [1] TRUE

You can also make a atomic vector with just one value. R saves single values as an atomic vector of length 1:

five <- 5
five
## [1] 5
is.vector(five)
## [1] TRUE
length(five)
## [1] 1
length(die)
## [1] 6

length returns the length of an atomic vector

You can create an integer vector by including a capital L with your input. You can create a character vector by surrounding your input in quotation marks:

int <- 1L
text <- "ace"

Each type of atomic vector has its own convention (described below). R will recognize the convention and use it to create an atomic vector of the appropriate type. If you’d like to make atomic vectors that have more than one element in them, you can combine an element with the c function. Use the same convention with each element:

int <- c(1L, 5L)
text <- c("ace", "hearts")

Vector types help R behave as you would expect. For example, R will do math with atomic vectors that contain numbers, but not with atomic vectors that contain character strings:

int <- c(1L, 5L)
text <- c("ace", "hearts")

sum(int)
## [1] 6
sum(text)
## Error in sum(text): invalid 'type' (character) of argument

5.1.1 Doubles

A double vector stores regular numbers. The numbers can be positive or negative, large or small, and have digits to the right of the decimal place or not. In general, R will save any number that you type in R as a double.

die <- c(1, 2, 3, 4, 5, 6)
die
## [1] 1 2 3 4 5 6

You’ll usually know what type of object you are working with in R (it will be obvious), but you can also ask R what type of object an object is with typeof.

typeof(die)
## [1] "double"

5.1.2 Integers

Integer vectors store integers, numbers that can be written without a decimal component.You can specifically create an integer in R by typing a number followed by an uppercase L.

int <- c(-1L, 2L, 4L)
int
## [1] -1  2  4
typeof(int)
## [1] "integer"

R won’t save a number as an integer unless you include the L. Integer numbers without the L will be saved as doubles.

Each double is accurate to about 16 significant digits. This introduces a little bit of error. In most cases, this rounding error will go unnoticed. However, in some situations, the rounding error can cause surprising results. For example, you may expect the result of the expression below to be zero, but it is not:

sqrt(2)^2 - 2
## [1] 4.440892e-16

These errors are known as floating-point errors, and doing arithmetic in these conditions is known as floating-point arithmetic. Floating-point arithmetic is not a feature of R; it is a feature of computer programming. Usually floating-point errors won’t be enough to ruin your day. Just keep in mind that they may be the cause of surprising results.

5.1.3 Characters

A character vector stores small pieces of text.

text <- c("Hello",  "World")
text
## [1] "Hello" "World"
typeof(text)
## [1] "character"
typeof("Hello")
## [1] "character"

The individual elements of a character vector are known as strings. Note that a string can contain more than just letters.

5.1.4 Logicals

Logical vectors store TRUEs and FALSEs, R’s form of Boolean data.

3 > 4
## [1] FALSE

Any time you type TRUE or FALSE in capital letters (without quotation marks), R will treat your input as logical data. R also assumes that T and F are shorthand for TRUE and FALSE, unless they are defined elsewhere (e.g. T <- 500). Since the meaning of T and F can change, its best to stick with TRUE and FALSE:

logic <- c(TRUE, FALSE, TRUE)
logic
## [1]  TRUE FALSE  TRUE
typeof(logic)
## [1] "logical"
typeof(F)
## [1] "logical"

5.1.5 Complex and Raw

Complex vectors store complex numbers. To create a complex vector, add an imaginary term to a number with i:

comp <- c(1 + 1i, 1 + 2i, 1 + 3i)
comp
## [1] 1+1i 1+2i 1+3i
typeof(comp)
## [1] "complex"

Raw vectors store raw bytes of data. Making raw vectors gets complicated, but you can make an empty raw vector of length n with raw(n):

raw(3)
## [1] 00 00 00
typeof(raw(3))
## [1] "raw"

Exercise 5.2 (Vector of Cards)

hand <- c("ace", "king", "queen", "jack", "ten")
hand
## [1] "ace"   "king"  "queen" "jack"  "ten"
typeof(hand)
## [1] "character"

5.3 Matrices

Matrices store values in a two-dimensional array, just like a matrix from linear algebra. To create one, first give matrix an atomic vector to reorganize into a matrix. Then, define how many rows should be in the matrix by setting the nrow argument to a number. matrix will organize your vector of values into a matrix with the specified number of rows. Alternatively, you can set the ncol argument, which tells R how many columns to include in the matrix:

m <- matrix(die, nrow = 2)
m
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6

matrix will fill up the matrix column by column by default, but you can fill the matrix row by row if you include the argument byrow = TRUE:

m <- matrix(die, nrow = 2, byrow = TRUE)
m
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6

5.4 Arrays

The array function creates an n-dimensional array. To use array, provide an atomic vector as the first argument, and a vector of dimensions as the second argument, now called dim:

ar <- array(c(11:14, 21:24, 31:34), dim = c(2, 2, 3))
ar
## , , 1
## 
##      [,1] [,2]
## [1,]   11   13
## [2,]   12   14
## 
## , , 2
## 
##      [,1] [,2]
## [1,]   21   23
## [2,]   22   24
## 
## , , 3
## 
##      [,1] [,2]
## [1,]   31   33
## [2,]   32   34

Exercise 5.3 (Make a Matrix) Solution 1

hand1 <- c("ace", "king", "queen", "jack", "ten", "spades", "spades", 
  "spades", "spades", "spades")

matrix(hand1, nrow = 5)
##      [,1]    [,2]    
## [1,] "ace"   "spades"
## [2,] "king"  "spades"
## [3,] "queen" "spades"
## [4,] "jack"  "spades"
## [5,] "ten"   "spades"
matrix(hand1, ncol = 2)
##      [,1]    [,2]    
## [1,] "ace"   "spades"
## [2,] "king"  "spades"
## [3,] "queen" "spades"
## [4,] "jack"  "spades"
## [5,] "ten"   "spades"
dim(hand1) <- c(5, 2)

Solution 2

hand2 <- c("ace", "spades", "king", "spades", "queen", "spades", "jack", 
  "spades", "ten", "spades")

matrix(hand2, nrow = 5, byrow = TRUE)
##      [,1]    [,2]    
## [1,] "ace"   "spades"
## [2,] "king"  "spades"
## [3,] "queen" "spades"
## [4,] "jack"  "spades"
## [5,] "ten"   "spades"
matrix(hand2, ncol = 2, byrow = TRUE)
##      [,1]    [,2]    
## [1,] "ace"   "spades"
## [2,] "king"  "spades"
## [3,] "queen" "spades"
## [4,] "jack"  "spades"
## [5,] "ten"   "spades"

5.7 Lists

Lists are like atomic vectors because they group data into a one-dimensional set. However, lists do not group together individual values; lists group together R objects, such as atomic vectors and other lists.

list1 <- list(100:130, "R", list(TRUE, FALSE))
list1
## [[1]]
##  [1] 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
## [20] 119 120 121 122 123 124 125 126 127 128 129 130
## 
## [[2]]
## [1] "R"
## 
## [[3]]
## [[3]][[1]]
## [1] TRUE
## 
## [[3]][[2]]
## [1] FALSE

**Exercise 5.5 (Use a List to Make a Card)

card <- list("ace", "hearts", 1)
card
## [[1]]
## [1] "ace"
## 
## [[2]]
## [1] "hearts"
## 
## [[3]]
## [1] 1

##5.8 Data Frames Data frames are the two-dimensional version of a list. They are far and away the most useful storage structure for data analysis, and they provide an ideal way to store an entire deck of cards.

Creating data frame with the data.frame function. Give data.frame any number of vectors, each separated with a comma. Each vector should be set equal to a name that describes the vector. data.frame will turn each vector into a column of the new data frame:

df <- data.frame(face = c("ace", "two", "six"),  
  suit = c("clubs", "clubs", "clubs"), value = c(1, 2, 3))
df
##   face  suit value
## 1  ace clubs     1
## 2  two clubs     2
## 3  six clubs     3

Names Give names to a list or vector when you create one of these objects. Use the same syntax as with data.frame:

list(face = "ace", suit = "hearts", value = 1)
## $face
## [1] "ace"
## 
## $suit
## [1] "hearts"
## 
## $value
## [1] 1
c(face = "ace", suit = "hearts", value = "one")
##     face     suit    value 
##    "ace" "hearts"    "one"

Each data frame is a list with class data.frame. You can see what types of objects are grouped together by a list (or data frame) with the str function:

typeof(df)
## [1] "list"
class(df)
## [1] "data.frame"
str(df)
## 'data.frame':    3 obs. of  3 variables:
##  $ face : chr  "ace" "two" "six"
##  $ suit : chr  "clubs" "clubs" "clubs"
##  $ value: num  1 2 3

R saved your character strings as factors. You can prevent this behavior by adding the argument stringsAsFactors = FALSE to data.frame:

df <- data.frame(face = c("ace", "two", "six"),  
  suit = c("clubs", "clubs", "clubs"), value = c(1, 2, 3),
  stringsAsFactors = FALSE)

Build an entire deck of card with data.frame.

deck <- data.frame(
  face = c("king", "queen", "jack", "ten", "nine", "eight", "seven", "six",
    "five", "four", "three", "two", "ace", "king", "queen", "jack", "ten", 
    "nine", "eight", "seven", "six", "five", "four", "three", "two", "ace", 
    "king", "queen", "jack", "ten", "nine", "eight", "seven", "six", "five", 
    "four", "three", "two", "ace", "king", "queen", "jack", "ten", "nine", 
    "eight", "seven", "six", "five", "four", "three", "two", "ace"),  
  suit = c("spades", "spades", "spades", "spades", "spades", "spades", 
    "spades", "spades", "spades", "spades", "spades", "spades", "spades", 
    "clubs", "clubs", "clubs", "clubs", "clubs", "clubs", "clubs", "clubs", 
    "clubs", "clubs", "clubs", "clubs", "clubs", "diamonds", "diamonds", 
    "diamonds", "diamonds", "diamonds", "diamonds", "diamonds", "diamonds", 
    "diamonds", "diamonds", "diamonds", "diamonds", "diamonds", "hearts", 
    "hearts", "hearts", "hearts", "hearts", "hearts", "hearts", "hearts", 
    "hearts", "hearts", "hearts", "hearts", "hearts"), 
  value = c(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 13, 12, 11, 10, 9, 8, 
    7, 6, 5, 4, 3, 2, 1, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 13, 12, 11, 
    10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
)

You should avoid typing large data sets in by hand whenever possible.It is always better to acquire large data sets as a computer file. You can then ask R to read the file and store the contents as an object.