── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4.9000 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Always use TRUE/FALSE and not T/F!
T
[1] TRUE
F
[1] FALSE
TRUE
[1] TRUE
FALSE
[1] FALSE
T and TRUE appear the same.
isTRUE(T)
[1] TRUE
isTRUE(TRUE)
[1] TRUE
But T/F can be reassigned.
T <-FALSEisTRUE(T)
[1] FALSE
TRUE/FALSE cannot be reassigned.
TRUE<-FALSE
Error in TRUE <- FALSE: invalid (do_set) left-hand side to assignment
The reason is because R has a short list of reserved words
?Reserved
25.1 Logical operators
25.1.1 NOT (!)
!TRUE
[1] FALSE
!FALSE
[1] TRUE
25.1.2 OR (|)
TRUE|TRUE
[1] TRUE
TRUE|FALSE
[1] TRUE
FALSE|TRUE
[1] TRUE
FALSE|FALSE
[1] FALSE
25.1.3 AND (&)
TRUE&TRUE
[1] TRUE
TRUE&FALSE
[1] FALSE
FALSE&TRUE
[1] FALSE
FALSE&FALSE
[1] FALSE
25.1.4 XOR (xor)
xor(TRUE, TRUE)
[1] FALSE
xor(TRUE, FALSE)
[1] TRUE
xor(FALSE, TRUE)
[1] TRUE
xor(FALSE, FALSE)
[1] FALSE
25.2 Multiple comparisons
The above operators are all vector operators and perform element-wise operations.
25.2.1 Elementwise comparisons
The operations above perform element-wise comparisons.
# Create logical vectorsb <-c(TRUE,FALSE)x <-rep(b, times =2)y <-rep(b, each =2)x
[1] TRUE FALSE TRUE FALSE
y
[1] TRUE TRUE FALSE FALSE
# Demonstrate element-wise operationsx | y
[1] TRUE TRUE TRUE FALSE
x & y
[1] TRUE FALSE FALSE FALSE
xor(x,y)
[1] FALSE TRUE TRUE FALSE
!x
[1] FALSE TRUE FALSE TRUE
25.2.2 Left-to-right comparison
If you want left-to-right comparisons, you can use && and ||.
TRUE&&TRUE&&TRUE
[1] TRUE
TRUE&&TRUE&&FALSE
[1] FALSE
TRUE&&FALSE&&TRUE
[1] FALSE
FALSE&&FALSE&&FALSE
[1] FALSE
TRUE||TRUE||TRUE
[1] TRUE
FALSE||FALSE||TRUE
[1] TRUE
FALSE||FALSE||FALSE
[1] FALSE
You will get a warning if you try to pass a vector to these left-to-right comparisons.
c(TRUE,FALSE) &&c(TRUE,TRUE)
Error in c(TRUE, FALSE) && c(TRUE, TRUE): 'length = 2' in coercion to 'logical(1)'
25.2.3 any()
The any() function returns true if any element in the vector is TRUE and FALSE otherwise.
# Demonstrate any()any(c(TRUE, TRUE, TRUE, TRUE))
[1] TRUE
any(c(TRUE, FALSE, FALSE, FALSE))
[1] TRUE
any(c(FALSE, FALSE, FALSE, FALSE))
[1] FALSE
25.2.4 all()
The all() function returns true if every element is TRUE and FALSE otherwise.
# Demonstrate all()all(c(TRUE, TRUE, TRUE, TRUE))
[1] TRUE
all(c(TRUE, FALSE, FALSE, FALSE))
[1] FALSE
all(c(FALSE, FALSE, FALSE, FALSE))
[1] FALSE
25.3 Comparisons
We will often use logical operations to compare objects including character and numeric quantities.
25.3.1 Numeric
Comparison of numerical quantities is typically much more straight-forward than chracter comparisons. But you do need to be careful of the numerical accuracy of numbers especially when trying to obtain exact matches.
# Assign two numericsa <-1b <-2# Inequalitiesa < b
[1] TRUE
a > b
[1] FALSE
a <= b
[1] TRUE
a >= b
[1] FALSE
We can also compare for exact values, but we may obtain unexpected results.
# Compare exactlya ==1
[1] TRUE
a ==2
[1] FALSE
a !=1
[1] FALSE
a !=2
[1] TRUE
a == b
[1] FALSE
a != b
[1] TRUE
Be careful with double precision
# sin() examplesin(0) ==0
[1] TRUE
sin(2*pi) ==0
[1] FALSE
When compare doubles, you probably want to determine if two values are close enough.
# Use toleranceabs(sin(2*pi) -0) < .Machine$double.eps^0.5
[1] TRUE
all.equal(sin(2*pi), 0)
[1] TRUE
An alternative is the near() function in the dplyr package. Unlike all.equal() this function returns FALSE when the two values are not near each other.
# near() uses a tolerancenear(sin(2*pi), 0)
[1] TRUE
near(1, 2)
[1] FALSE
25.3.2 Character
There are a variety of ways to compare character objects:
exact match
ignore capitalization matching
match an element of a set
substring matching
# Exact comparisons"a"=="a"
[1] TRUE
"a"!="a"
[1] FALSE
"a"==""
[1] FALSE
"a"!="b"
[1] TRUE
"a"=="A"
[1] FALSE
If you want to ignore capitalization, you can use the tolower() (or toupper()) function to change the capitalization.
# Match ignoring capitalization"a"=="A"
[1] FALSE
"a"==tolower("A")
[1] TRUE
"string"=="StRiNG"
[1] FALSE
"string"==tolower("StRiNG")
[1] TRUE
We may also have a set of strings and we are interested in whether our string is in that set
If you want to test if the string has any collection of characters, you can use regular expression (regex) matching.
# Regular expression help?regexp
R has its own version of regular expression matching. To use the built-in character classes, you will need to wrap them in an additional set of square brackets.
# R built-in character classesgrepl('[[:alnum:]]', c("a", "1", "a1", "$"))