What is TRUE and FALSE?

Compare prices to get TRUE and FALSE, combine conditions with and, or and not, and count how many closes sat above a level.

A comparison in R hands back TRUE or FALSE, not a number. R calls that type logical.

In this lesson I compare one price to its average, join two conditions into a single answer, then run one comparison across five closes and count how many came out TRUE.

Step 1. Compare two numbers

There are six comparison operators: > greater than, < less than, >= at least, <= at most, == equal to, != not equal to.

price   <- 187.20               # today's close
average <- 185.00               # the average of the last few closes

print(price > average)          # -> [1] TRUE
[1] TRUE
print(price < average)          # -> [1] FALSE
[1] FALSE
print(price >= average)         # -> [1] TRUE
[1] TRUE
print(price <= average)         # -> [1] FALSE
[1] FALSE
print(price == average)         # -> [1] FALSE
[1] FALSE
print(price != average)         # -> [1] TRUE
[1] TRUE

The answer is a value like any other, so you can name it with <- and keep it.

above <- price > average        # holds the answer, not the question
print(above)                    # -> [1] TRUE
[1] TRUE
print(class(above))             # -> [1] "logical"
[1] "logical"

class() says "logical". That is the third type after "numeric" and "character".

Two equals signs and an arrow do different jobs. <- puts a value into a name. == asks whether two values match and gives back TRUE or FALSE.

x <- 5              # <- puts 5 into x and prints nothing
print(x == 5)       # -> [1] TRUE
[1] TRUE
print(x == 6)       # -> [1] FALSE
[1] FALSE

Step 2. And, or, not

& is true when both sides are true. | is true when at least one side is. ! flips an answer to its opposite.

last_close <- 187.20                          # one day's close
volume     <- 900000                          # shares traded that day

print(last_close > 185 & volume > 1000000)    # -> [1] FALSE
[1] FALSE
print(last_close > 185 | volume > 1000000)    # -> [1] TRUE
[1] TRUE
print(!(last_close > 185))                    # -> [1] FALSE
[1] FALSE

The close cleared 185 but the volume fell short of a million, so & gives FALSE and | gives TRUE. The last line asks whether the close is above 185 and then flips the TRUE to FALSE.

Step 3. One comparison, five answers

Comparison operators work element by element, the same way arithmetic did. Compare a whole vector to one number and you get one answer per element.

closes <- c(185.40, 187.20, 184.90, 188.10, 190.50)   # five closing prices in order
level  <- 186.00                                      # the line I am measuring them against

above <- closes > level                               # one TRUE or FALSE per close
print(above)                                          # -> [1] FALSE  TRUE FALSE  TRUE  TRUE
[1] FALSE  TRUE FALSE  TRUE  TRUE
print(length(above))                                  # -> [1] 5
[1] 5

Check it by hand: 185.40 is below 186, 187.20 is above, 184.90 is below, 188.10 and 190.50 are above. Five prices in, five answers out. R pads TRUE with an extra space so the column lines up with FALSE.

Step 4. Count the TRUEs

TRUE counts as 1 and FALSE as 0 whenever a logical vector meets arithmetic. So sum() gives the number of TRUEs and mean() gives the fraction.

print(sum(c(TRUE, FALSE, TRUE)))   # -> [1] 2      <- TRUE is 1, FALSE is 0
[1] 2
print(sum(above))                  # -> [1] 3      <- three closes sat above 186
[1] 3
print(mean(above))                 # -> [1] 0.6    <- three out of five
[1] 0.6

any() asks whether at least one element is TRUE. all() asks whether every one is.

print(any(above))            # -> [1] TRUE    <- at least one close beat 186
[1] TRUE
print(all(above))            # -> [1] FALSE   <- but not all of them
[1] FALSE
print(any(closes > 200))     # -> [1] FALSE   <- nothing reached 200
[1] FALSE
print(all(closes > 180))     # -> [1] TRUE    <- every close cleared 180
[1] TRUE

& and | are vectorised too, so you can ask for two conditions across the whole vector at once.

band <- closes > level & closes < 190   # above 186 and below 190
print(band)                             # -> [1] FALSE  TRUE FALSE  TRUE FALSE
[1] FALSE  TRUE FALSE  TRUE FALSE
print(sum(band))                        # -> [1] 2
[1] 2

187.20 and 188.10 sit inside the band. 190.50 clears 186 but fails the second test, so it comes out FALSE.

Your turn

Take closes <- c(101.0, 99.5, 100.2, 97.8, 103.4) and a level of 100. How many closes are above the level, and what fraction is that? Did any close reach 105, and did every close stay above 95?

closes <- c(101.0, 99.5, 100.2, 97.8, 103.4)   # five closes
level  <- 100.0                                # the level to compare against

above <- closes > level                        # one answer per close
print(above)                                   # -> [1]  TRUE FALSE  TRUE FALSE  TRUE
print(sum(above))                              # -> [1] 3
print(mean(above))                             # -> [1] 0.6

print(any(closes > 105))                       # -> [1] FALSE
print(all(closes > 95))                        # -> [1] TRUE