2.3 Subsetting Vectors
Quite often we need to select one or more elements from a vector. The subsetting operator [
allows us to do this.
Recall the vector heights
:
heights
## Scarecrow Tinman Lion Dorothy Toto Boq
## 72 70 69 58 NA 45
If we want the fourth element, we ask for it with the subsetting operator like this:
4] heights[
## Dorothy
## 58
If we want two or more elements, then we specify their indices in a vector. Thus, to get the first and fifth elements, we might do this:
<- c(1,5)
desired heights[desired]
## Scarecrow Toto
## 72 NA
We could also ask for them directly:
c(1,5)] heights[
## Scarecrow Toto
## 72 NA
Negative numbers are significant in subsetting:
-2] #select all but second element heights[
## Scarecrow Lion Dorothy Toto Boq
## 72 69 58 NA 45
-c(1,3)] # all but first and third heights[
## Tinman Dorothy Toto Boq
## 70 58 NA 45
If you specify a nonexistent index, you get NA
, the reasonable result:
7] heights[
## <NA>
## NA
Patterned vectors are quite useful for subsetting. If you want the first three elements of heights
, you don’t have to type heights[c(1,2,3)]
. Instead you can just say:
1:3] heights[
## Scarecrow Tinman Lion
## 72 70 69
The following gives the same as heights
:
1:length(heights)] heights[
## Scarecrow Tinman Lion Dorothy Toto Boq
## 72 70 69 58 NA 45
If you desire to quickly provide names for a vector, subsetting can help:
<- c(23, 14, 82, 33, 33, 45)
vec names(vec) <- LETTERS[1:length(vec)]
vec
## A B C D E F
## 23 14 82 33 33 45
If a vector has names we can refer to its elements using the subsetting operator and those names:
"Tinman"] heights[
## Tinman
## 70
c("Scarecrow", "Boq")] heights[
## Scarecrow Boq
## 72 45
Finally, we can use subsetting to modify parts of a vector. For example, Dorothy’s height is reported as:
"Dorothy"] heights[
## Dorothy
## 58
If Dorothy grows two inches, then we can modify her height as follows:
"Dorothy"] <- 60 heights[
We can replace more than one element, of course. Thus:
c("Scarecrow", "Boq")] <- c(73, 46) heights[
The subset of indices may be as complex as you like:
<- c(3,4,5,6,7,8)
vec seq(from = 2, to = 6, by = 2)] <- c(100, 200, 300)
vec[ vec
## [1] 3 100 5 200 7 300
In the above example, seq(2,6,2)
identified 2, 4 and 6 as the indices of elements of vec
that were to be replaced by the corresponding elements of c(100, 200, 300)
.
We can even use subsetting to rearrange the elements of a vector. Consider the example below:
<- c("Oz", "Toto", "Boq", "Glinda")
inhabitants <- inhabitants[c(3,4,1,2)]
permuted permuted
## [1] "Boq" "Glinda" "Oz" "Toto"
2.3.1 Practice Exercises
We’ll work with the following vector:
<- c(4, 3, 7, 10, 5, 3, 8) practiceVec
Select the fifth element of
practiceVec
.Select the third and sixth elements of
practiceVec
.Select the first, second, third and fourth elements of
practiceVec
.How would you select the last element of the vector
mysteryVec
if you did not know how many elements it had?Select all but the fourth element of
practiceVec
.Select all but the fourth and sixth elements of
practiceVec
.Select the even-numbered elements of
practiceVec
.Replace the third element of
practiceVec
with the number 5.Replace the even-numbered elements of
practiceVec
with zeroes.Replace the second, third and fifth elements of
practiceVec
with 3, 10, and 20 respectively.Reverse the order of the elements of
practiceVec
.
2.3.2 Solutions to Practice Exercises
practiceVec[5]
practiceVec[c(3,6)]
practiceVec[1:4]
mysteryVec[length(mysteryVec)]
practiceVec[-4]
practiceVec[-c(4,5)]
practiceVec[seq(2, length(practiceVec), by = 2)]
practiceVec[3] <- 5
Here is one way:
<- rep(0, times = length(seq(2 length(practiceVec)))) zeroes seq(2, length(practiceVec), by = 2)] <- zeroes practiceVec[
Here’s a quicker way:
seq(2, length(practiceVec), by = 2)] <- 0 practiceVec[
The latter approach involves “recycling” the zero. We’ll discuss recycling soon.
practiceVec[c(2, 3, 5)] <- c(3, 10, 20)
practiceVec[length(practiceVec):1]