R Lesson #3 - Logicals operations
Both integers and logicals require 32 bits per element in R. The primary difference is that logicals can only be TRUE, FALSE, or NA. Logicals are ubiquitous, as they are the output of many comparisons and other functions, as demonstrated below.# coercing a numeric to integer
> as.integer(1.2) # truncated toward zero
[1] 1
> as.integer(-1.2) # truncated toward zero
[1] -1
>
> # several useful functions that return doubles
> floor(1.2)
[1] 1
> ceiling(1.2)
[1] 2
> round(1.2, digits=2)
[1] 1.2
>
> # is.numeric is different than is.double
> is.numeric(1.2) # interpretable as number
[1] TRUE
> is.numeric(1L) # integers are also TRUE
[1] TRUE
> is.double(1.2)
[1] TRUE
> is.double(1L)
[1] FALSE
>
> # coercion to logical: 0 = FALSE, otherwise TRUE
> as.logical(0)
[1] FALSE
> is.logical(1.2)
[1] FALSE
> as.logical(1.2)
[1] TRUE
> is.logical(as.logical(1.2))
[1] TRUE
>
> # comparisons return a logical vector
> x <- 1
> y <- 2
> x > y
[1] FALSE
> x >= y
[1] FALSE
> x == y
[1] FALSE
> 2*x == y # multiplication before equality
[1] TRUE
>
> # accessing help for any function
> ?Syntax # order of operations
> ?round # obtain help for any function
> ?`+` # some functions require back ticks
>
> # initialize a logical vector
> z <- logical(100)
> object.size(z)/length(z)
4.4 bytes
> # Note that each logical element is stored in 4 bytes
z[2:3] <- TRUE
> head(z)
[1] FALSE TRUE TRUE FALSE FALSE FALSE
> z[5] <- T # T is a reserved word
> head(z)
[1] FALSE TRUE TRUE FALSE TRUE FALSE
>
> # common names should not be changed
> T <- "hello" # Never do this!
> z[5] <- T
> head(z) # characters now!
[1] "FALSE" "TRUE" "TRUE" "FALSE" "hello" "FALSE"
> rm(T) # remove the variable `T`
> T # everything is back to normal
[1] TRUE
>
> # Reserved names do not permit assignment
> ?Reserved
> TRUE <- "hello" # Error
Error in TRUE <- "hello" : invalid (do_set) left-hand side to assignment
> # common names to avoid overwriting:
> c # function names
function (..., recursive = FALSE) .Primitive("c")
> T # TRUE shorthand
[1] TRUE
> F # FALSE shorthand
[1] FALSE
> letters # lower-case letters
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l"
[13] "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x"
[25] "y" "z"
> LETTERS # upper-case letters
[1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L"
[13] "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X"
[25] "Y" "Z"
> pi # 3.14...
[1] 3.141593
x1 <- 0.5 - 0.3
> x2 <- 0.3 - 0.1
> x1 == x2 # comparison of numerics
[1] FALSE
> x1 != x2
[1] TRUE
> print(x1, digits=22)
[1] 0.2000000000000000111022
> print(x2, digits=22)
[1] 0.1999999999999999833467
> all.equal(x1, x2) # TRUE
[1] TRUE
> # but most of the time equality works as expected
> 2/3 == 2*(1/3) # TRUE
[1] TRUE
a <- c(T, T, F, F)
> a
[1] TRUE TRUE FALSE FALSE
> !a
[1] FALSE FALSE TRUE TRUE
> b <- c(T, F, T, F)
> a & b # Truth table for AND operation
[1] TRUE FALSE FALSE FALSE
> a | b # Truth table for OR operation
[1] TRUE TRUE TRUE FALSE
> a && b # only uses the first element with no Warning!
[1] TRUE
> a || b # only uses the first element with no Warning!
[1] TRUE
> a[2] && b[2]
[1] FALSE
> a[2] || b[2]
[1] TRUE
> xor(a, b) # Exclusive OR (XOR)
[1] FALSE TRUE TRUE FALSE
r <- runif(100) # 100 random numbers
> r # roughly uniformly distributed between 0 and 1
[1] 0.85667156 0.34026964 0.44424143 0.48037833
[5] 0.87667115 0.65841114 0.92110802 0.21177947
[9] 0.30524428 0.12875139 0.46554814 0.73656323
[13] 0.78056957 0.35762074 0.07626947 0.03351947
[17] 0.77606616 0.06700093 0.52778631 0.48712420
[21] 0.66335777 0.56610838 0.44025036 0.63570422
[25] 0.99940558 0.20624952 0.31441187 0.77470678
[29] 0.63578651 0.65580460 0.86104108 0.37896363
[33] 0.76623888 0.22145695 0.25397960 0.07959553
[37] 0.72126320 0.69776325 0.09309901 0.56508622
[41] 0.25661917 0.82514489 0.56554523 0.06238280
[45] 0.96626279 0.74489289 0.13250879 0.46242389
[49] 0.96865750 0.74094259 0.38335198 0.66505184
[53] 0.47497121 0.03714927 0.69987399 0.13834235
[57] 0.68731832 0.18809398 0.60494391 0.33094660
[61] 0.80798206 0.44554323 0.07992541 0.93656027
[65] 0.06502416 0.78303341 0.94759327 0.06641417
[69] 0.48330766 0.24743624 0.96726025 0.52037367
[73] 0.17429884 0.33773523 0.02584235 0.13105126
[77] 0.23764974 0.98281393 0.77911002 0.19064267
[81] 0.58837599 0.94003876 0.39637532 0.38549449
[85] 0.36373678 0.61239700 0.72690764 0.37245687
[89] 0.92261563 0.46138683 0.89940080 0.87923886
[93] 0.30293246 0.57432447 0.68368253 0.75951094
[97] 0.99441555 0.13772023 0.65303211 0.92292185
> r < 0.5
[1] FALSE TRUE TRUE TRUE FALSE FALSE FALSE TRUE
[9] TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE
[17] FALSE TRUE FALSE TRUE FALSE FALSE TRUE FALSE
[25] FALSE TRUE TRUE FALSE FALSE FALSE FALSE TRUE
[33] FALSE TRUE TRUE TRUE FALSE FALSE TRUE FALSE
[41] TRUE FALSE FALSE TRUE FALSE FALSE TRUE TRUE
[49] FALSE FALSE TRUE FALSE TRUE TRUE FALSE TRUE
[57] FALSE TRUE FALSE TRUE FALSE TRUE TRUE FALSE
[65] TRUE FALSE FALSE TRUE TRUE TRUE FALSE FALSE
[73] TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE
[81] FALSE FALSE TRUE TRUE TRUE FALSE FALSE TRUE
[89] FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE
[97] FALSE TRUE FALSE FALSE
> # `which` takes a logical input
> w <- which(r < 0.5)
> w # indices that are TRUE, where r < 0.5
[1] 2 3 4 8 9 10 11 14 15 16 18 20 23 26 27 32
[17] 34 35 36 39 41 44 47 48 51 53 54 56 58 60 62 63
[33] 65 68 69 70 73 74 75 76 77 80 83 84 85 88 90 93
[49] 98
> r[w]
[1] 0.34026964 0.44424143 0.48037833 0.21177947
[5] 0.30524428 0.12875139 0.46554814 0.35762074
[9] 0.07626947 0.03351947 0.06700093 0.48712420
[13] 0.44025036 0.20624952 0.31441187 0.37896363
[17] 0.22145695 0.25397960 0.07959553 0.09309901
[21] 0.25661917 0.06238280 0.13250879 0.46242389
[25] 0.38335198 0.47497121 0.03714927 0.13834235
[29] 0.18809398 0.33094660 0.44554323 0.07992541
[33] 0.06502416 0.06641417 0.48330766 0.24743624
[37] 0.17429884 0.33773523 0.02584235 0.13105126
[41] 0.23764974 0.19064267 0.39637532 0.38549449
[45] 0.36373678 0.37245687 0.46138683 0.30293246
[49] 0.13772023
>
> # all returns TRUE if all inputs are TRUE
> all(r[w]==r[r < 0.5])
[1] TRUE
> # any returns TRUE if any input is TRUE
> any(r > 1)
[1] FALSE
>
> min(r)
[1] 0.02584235
> max(r)
[1] 0.9994056
> mean(r)
[1] 0.5178385
> which.min(r)
[1] 75
> which(r==min(r))
[1] 75
> r <- c(r, r) # repeat `r` twice
> which.max(r) # first occurrence only
[1] 25
> which(r==max(r)) # all occurrences
[1] 25 125
set.seed(123L)
> r1 <- rnorm(100) # 100 randomly distributed numbers
> set.seed(123L)
> r2 <- rnorm(100) # restart from the same point
> all(r1 == r2) # the same set of random numbers
[1] TRUE
> r3 <- rnorm(100) # continue without restarting
> any(r1 == r3) # all different random numbers
[1] FALSE
> length(which(r1 > r3))/length(r3) # about half
[1] 0.58
> set.seed(NULL) # re-initializes the seed