library("tidyverse")
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.4.0 ✔ purrr 0.3.5
## ✔ tibble 3.1.8 ✔ dplyr 1.0.10
## ✔ tidyr 1.2.1 ✔ stringr 1.4.1
## ✔ readr 2.1.3 ✔ forcats 0.5.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
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 can be reassigned.
T <- FALSE
isTRUE(T)
## [1] FALSE
TRUE 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
!TRUE
## [1] FALSE
!FALSE
## [1] TRUE
TRUE | TRUE
## [1] TRUE
TRUE | FALSE
## [1] TRUE
FALSE | TRUE
## [1] TRUE
FALSE | FALSE
## [1] FALSE
TRUE & TRUE
## [1] TRUE
TRUE & FALSE
## [1] FALSE
FALSE & TRUE
## [1] FALSE
FALSE & FALSE
## [1] FALSE
xor(TRUE, TRUE)
## [1] FALSE
xor(TRUE, FALSE)
## [1] TRUE
xor(FALSE, TRUE)
## [1] TRUE
xor(FALSE, FALSE)
## [1] FALSE
The operations above perofrm elementwise comparisons.
b <- 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
x | 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
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)
## Warning in c(TRUE, FALSE) && c(TRUE, TRUE): 'length(x) = 2 > 1' in coercion to
## 'logical(1)'
## Warning in c(TRUE, FALSE) && c(TRUE, TRUE): 'length(x) = 2 > 1' in coercion to
## 'logical(1)'
## [1] TRUE
any(c(TRUE, TRUE, TRUE, TRUE))
## [1] TRUE
any(c(TRUE, FALSE, FALSE, FALSE))
## [1] TRUE
any(c(FALSE, FALSE, FALSE, FALSE))
## [1] FALSE
all(c(TRUE, TRUE, TRUE, TRUE))
## [1] TRUE
all(c(TRUE, FALSE, FALSE, FALSE))
## [1] FALSE
all(c(FALSE, FALSE, FALSE, FALSE))
## [1] FALSE
"a" == "a"
## [1] TRUE
"a" != "a"
## [1] FALSE
"a" == ""
## [1] FALSE
"a" != "b"
## [1] TRUE
grepl("a", "abcd")
## [1] TRUE
grepl("a", letters)
## [1] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE
grepl("a", LETTERS, ignore.case = TRUE)
## [1] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE
a <- 1
b <- 2
a < b
## [1] TRUE
a > b
## [1] FALSE
a <= b
## [1] TRUE
a >= b
## [1] FALSE
a == 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(0) == 0
## [1] TRUE
sin(2*pi) == 0
## [1] FALSE
abs(sin(2*pi) - 0) < .Machine$double.eps^0.5
## [1] TRUE
near(sin(2*pi), 0)
## [1] TRUE
Not all seemingly logical functions return TRUE/FALSE.
all.equal(1,1)
## [1] TRUE
all.equal(1,2)
## [1] "Mean relative difference: 1"
all(c(TRUE, FALSE))
## [1] FALSE
all(c(TRUE, FALSE, NA))
## [1] FALSE
all(c(TRUE, TRUE, NA))
## [1] NA
This can cause issues in flow control
if (all(c(TRUE, TRUE, NA))) {
# Do something
}
## Error in if (all(c(TRUE, TRUE, NA))) {: missing value where TRUE/FALSE needed
The isTRUE()
and isFALSE()
functions ALWAYS
resolve to TRUE/FALSE.
isTRUE(TRUE)
## [1] TRUE
isTRUE(NA)
## [1] FALSE
isTRUE(1)
## [1] FALSE
isTRUE(as.logical(NA))
## [1] FALSE
isTRUE(as.logical(1)) # all non-zero numeric values are coerced to TRUE
## [1] TRUE
isTRUE(as.logical(2))
## [1] TRUE
isTRUE(as.logical(1e-16))
## [1] TRUE
isFALSE(FALSE)
## [1] TRUE
isFALSE(NA)
## [1] FALSE
isFALSE(1)
## [1] FALSE
isFALSE(as.logical(NA))
## [1] FALSE
isFALSE(as.logical(0)) # only 0 is coerced to FALSE
## [1] TRUE
isFALSE(as.logical(2))
## [1] FALSE
isTRUE(all.equal(1,2))
## [1] FALSE
isFALSE(all.equal(1,2))
## [1] FALSE
isFALSE(!all.equal(1,1))
## [1] TRUE
isTRUE(NA)
## [1] FALSE
isFALSE(NA)
## [1] FALSE