In last section, you learned how to do vector subsetting, which yields a subvector of the original vector. Let’s take a numeric vector
x <- 1:5 for example. In order to get a subvector of
x with values bigger than 3, you can first create a logical vector
xb3 <- x > 3, then use the
xb3 as the index to do vector subsetting.
<- 1:5 x <- x > 3 xb3 <- x[xb3] set1 set1#>  4 5
Here, the numeric vector
set1 has values
4 5. You can get another subvector of
x by running the following codes.
<- x <= 4 xs4 <- x[xs4]set2
Sometimes, you may want to get a subvector with more than one conditions. For example, how can we find the subvector of
x with values larger than 3 and less than or equal to 4? In this section, we will introduce several logical operators and use them to get subvectors. Here, we only introduce how to apply these operators on logical vectors.
Before we get started, let’s create another numeric vector
y and compare it to
9 separately, then you will get two logical vectors with same values as
<- 6:10 y <- y > 8 #xb3 is the same as yb8 yb8 <- y <= 9 #xs4 is the same as ys9ys9
The first operator we want to introduce is
!, often called the NOT operator. The NOT operator returns the opposite logical value of the input logical values. It is intuitive to understand since if something is NOT FALSE, then it is TRUE; and if it is NOT TRUE, then it has to be FALSE.
It is summarized in the following table.
Let’s see what happens if you apply the NOT operator on a logical vector.
!c(FALSE, FALSE, FALSE, TRUE, TRUE) #the opposite of a logical vector #>  TRUE TRUE TRUE FALSE FALSE
From the result, you get another logical vector with the same length as the original one. The value of each element in the new vector is the opposite of the corresponding value in the original vector.
xb3 is also a logical vector, you can try to apply
xb3, and use
!xb3 (which is also a logical vector) to do vector subsetting. Guess what will you get?
!xb3 #>  TRUE TRUE TRUE FALSE FALSE <- x[!xb3] set3 set3#>  1 2 3
Of course the resulting numeric vector
set3 will have
1 2 3 as values! As a result,
set3 are complement of each other from the whole vector
From Section 2.6, you have learned that if the logical vectors you use are identical, you will get the same result after doing vector subsetting. So if you use
!yb8 to do vector subsetting, you will get a vector with the same result as that when you use
!yb8] x[#>  1 2 3
Secondly, we will introduce the AND operator
&. Similar to making comparisons between two logical vectors,
& performs comparisons elementwisely, which generates a vector with the same length if the input logical vectors are of the same length or with the same length as that of the longer vector. For each location of the resulting vector, the value will be
TRUE if both values in the same location of the input two vectors are both
TRUE, and will be
FALSE otherwise. In particular, for each element, we have the following summary.
|TRUE & TRUE||TRUE|
|TRUE & FALSE||FALSE|
|FALSE & TRUE||FALSE|
|FALSE & FALSE||FALSE|
Let’s see an example of the AND operation between two logical vectors of the same length.
c(FALSE, FALSE, FALSE, TRUE, TRUE) & c(TRUE, TRUE, FALSE, TRUE, FALSE) #>  FALSE FALSE FALSE TRUE FALSE
As explained before, the AND operator works elementwisely and the intermediate step is as below.
c(FALSE & TRUE, FALSE & TRUE, FALSE & FALSE, TRUE & TRUE, TRUE & FALSE) #>  FALSE FALSE FALSE TRUE FALSE
As you can see from the result, only the fourth element is
TRUE since the fourth element of both input logical vectors is
Since the AND operator makes comparisons elementwisely, the recycling rule also works here. But normally we want one vector with length > 1 and another one with length 1.
c(FALSE, FALSE, FALSE, TRUE, TRUE) & FALSE #>  FALSE FALSE FALSE FALSE FALSE
After learning about the AND operator, you can now get a subvector of
x with value(s) > 3 and <= 4 easily. At the beginning of this section, you have created two logical vectors
xs4 by making comparisons, then let’s apply
& on these vectors,
& xs4 xb3 #>  FALSE FALSE FALSE TRUE FALSE
From the result, you know that both
xs4 have value
TRUE for the fourth element, which means the statement that the value is > 3 and <= 4 is TRUE for the fourth element in
x. Then you can use
xb3 & xs4 (a logical vector) to do vector subsetting.
& xs4] x[xb3 #>  4
Here, you get a subvector of
x with value
ys9 have same values, you will get the same result if you include
ys9 to get a subvector. You can try the following codes by yourself.
& ys9] x[xb3 & ys9]x[yb8
Note that the logical vector used to do vector subsetting needs to be of the same length as the original vector. Since
y have the same length, the logical vectors from above can be used to get subvectors of
y as well. You will get the same result from the following four codes.
& xs4] y[xb3 & ys9] y[yb8 & ys9] y[xb3 & xs4]y[yb8
The OR operator
| works similarly to the AND operator
&, but the difference is that
TRUE if there is at least one
TRUE among the two elements at the same location in two vectors. Let’s go through some examples together.
|TRUE | TRUE||TRUE|
|TRUE | FALSE||TRUE|
|FALSE | TRUE||TRUE|
|FALSE | FALSE||FALSE|
Let’s try another example on length > 1 vectors and compare the result with that when we use the AND operator
c(FALSE, FALSE, FALSE, TRUE, TRUE) | c(TRUE, TRUE, FALSE, TRUE, FALSE) #>  TRUE TRUE FALSE TRUE TRUE c(FALSE, FALSE, FALSE, TRUE, TRUE) & c(TRUE, TRUE, FALSE, TRUE, FALSE) #>  FALSE FALSE FALSE TRUE FALSE
You also get a length-5 logical vector with an elementwise OR operation
|, which is very different from the result with AND operation
Of course you can also use
xb3 | xs4 to do vector subsetting, with it being another length-5 logical vector.
| xs4] x[xb3 #>  1 2 3 4 5
Wow! You get all five elements of
x! That’s because the statement “the value is either > 3 or <= 4” is TRUE for all elements in
Last but not least, we introduce the exclusive OR operator
xor. From the name, it’s easy to know that
xor is an extended form of
|. Here are some examples,
Different from the OR operator,
TRUE when there is one and only one
TRUE among values of these two logical vectors. If these two vectors have the same value, both
TRUE or both
FALSE, you will get the value
For two length > 1 vectors,
xor() again performs comparisons elementwisely. You can check the result by yourself!
xor(c(FALSE, FALSE, FALSE, TRUE, TRUE), c(TRUE, TRUE, TRUE, TRUE, FALSE)) #>  TRUE TRUE TRUE FALSE TRUE
Since you also get a logical vector after applying
xor(), you can use it to do vector subsetting. Using different combinations to do vector subsetting is interesting. Try them!
xor(xb3, xs4)] x[xor(!xb3, ys9)] y[xor(yb8, !ys9)]y[
Let’s summarize the logical operators between two vectors.
- The NOT operator
!gives the opposite of each value.
- The AND operator
TRUEif both are
- The OR operator
TRUEif at least one is
- The exclusive OR operator
TRUEif one and only one is
Consider the vector
v1 <- seq(from = 1, to = 100, by = 3), and
v2 <- sqrt(v1).
Find the subvector of
v1with values bigger or equal to 30 and less than 60. And assign the subvector to name v1s.
Find the subvector of
v2such that the corresponding value of
v1is less than 20 or larger than 50.
Use an example to verify \(xor(a, b) = (!a & b) | (a & !b)\)