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 closeaverage <-185.00# the average of the last few closesprint(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 questionprint(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 nothingprint(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 closevolume <-900000# shares traded that dayprint(last_close >185& volume >1000000) # -> [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 orderlevel <-186.00# the line I am measuring them againstabove <- closes > level # one TRUE or FALSE per closeprint(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
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?
TipShow answer
closes <-c(101.0, 99.5, 100.2, 97.8, 103.4) # five closeslevel <-100.0# the level to compare againstabove <- closes > level # one answer per closeprint(above) # -> [1] TRUE FALSE TRUE FALSE TRUEprint(sum(above)) # -> [1] 3print(mean(above)) # -> [1] 0.6print(any(closes >105)) # -> [1] FALSEprint(all(closes >95)) # -> [1] TRUE