How do I take part of a vector?

Pick elements out of a vector by position, by dropping, and by a condition, then average the last five closes.

Square brackets take part of a vector. closes[1] is the first element, closes[2:4] is the second to the fourth, and closes[closes > 190] is every element above 190.

In this lesson I pull single elements and ranges out of a week and a half of closing prices, show what a negative index does in R, select by a condition, and average the last five closes.

Step 1. Pick by position

R counts from 1. The first element is closes[1]. Python counts from 0.

closes <- c(185.40, 187.20, 184.90, 188.10, 190.50, 191.30, 189.70, 193.20)

print(closes[1])                 # -> [1] 185.4    <- the first close, not closes[0]
[1] 185.4
print(closes[3])                 # -> [1] 184.9
[1] 184.9
print(length(closes))            # -> [1] 8
[1] 8
print(closes[length(closes)])    # -> [1] 193.2    <- the last close
[1] 193.2

Put a vector inside the brackets and you get several elements back. 2:4 is the vector 2, 3, 4, and both ends are included, so closes[2:4] returns three prices. Python’s closes[2:4] would return two.

print(closes[2:4])          # -> [1] 187.2 184.9 188.1
[1] 187.2 184.9 188.1
print(closes[c(1, 5, 8)])   # -> [1] 185.4 190.5 193.2    <- any positions, any order
[1] 185.4 190.5 193.2

head() and tail() take from each end without you counting.

print(head(closes, 3))   # -> [1] 185.4 187.2 184.9
[1] 185.4 187.2 184.9
print(tail(closes, 3))   # -> [1] 191.3 189.7 193.2
[1] 191.3 189.7 193.2
print(tail(closes, 1))   # -> [1] 193.2    <- the last element
[1] 193.2

tail(closes, 1) is how you take the last element in R.

Two vectors of the same length line up, so one index reads both.

days <- c("Mon", "Tue", "Wed", "Thu", "Fri", "Mon", "Tue", "Wed")

print(days[4])     # -> [1] "Thu"
[1] "Thu"
print(closes[4])   # -> [1] 188.1    <- the close that belongs to Thu
[1] 188.1

Step 2. A negative index drops

In Python, closes[-1] is the last element. In R it is everything except the first.

print(closes[-1])          # -> [1] 187.2 184.9 188.1 190.5 191.3 189.7 193.2
[1] 187.2 184.9 188.1 190.5 191.3 189.7 193.2
print(length(closes[-1]))  # -> [1] 7    <- one shorter, the first one is gone
[1] 7
print(closes[-c(1, 2)])    # -> [1] 184.9 188.1 190.5 191.3 189.7 193.2
[1] 184.9 188.1 190.5 191.3 189.7 193.2

The minus sign means remove, not count backwards. R has no index that counts from the end, which is why tail(closes, 1) exists.

Dropping is how you line a vector up against itself. Drop the first element and you get every close from the second day on. Drop the last and you get every close from the day before. The two have the same length, so they subtract element by element.

later   <- closes[-1]                       # every close from day 2 on
earlier <- closes[-length(closes)]          # every close from day 1 to day 7

print(later)                                # -> [1] 187.2 184.9 188.1 190.5 191.3 189.7 193.2
[1] 187.2 184.9 188.1 190.5 191.3 189.7 193.2
print(earlier)                              # -> [1] 185.4 187.2 184.9 188.1 190.5 191.3 189.7
[1] 185.4 187.2 184.9 188.1 190.5 191.3 189.7
change <- later - earlier                   # the day over day price change
print(round(change, 2))                     # -> [1]  1.8 -2.3  3.2  2.4  0.8 -1.6  3.5
[1]  1.8 -2.3  3.2  2.4  0.8 -1.6  3.5
print(length(change))                       # -> [1] 7    <- eight prices give seven changes
[1] 7

Step 3. Pick by a condition

closes > 190 gives a TRUE or FALSE for every element. Put that inside the brackets and R keeps the elements where it says TRUE.

print(closes > 190)          # -> [1] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE  TRUE
[1] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE  TRUE
print(closes[closes > 190])  # -> [1] 190.5 191.3 193.2
[1] 190.5 191.3 193.2
print(sum(closes > 190))     # -> [1] 3    <- TRUE counts as 1
[1] 3

The same TRUE and FALSE vector reads days, because the two vectors line up.

print(days[closes > 190])    # -> [1] "Fri" "Mon" "Wed"
[1] "Fri" "Mon" "Wed"

Step 4. The mean of a slice

tail(closes, 5) is the last five prices. mean() averages them.

last5 <- tail(closes, 5)      # the five most recent closes
print(last5)                  # -> [1] 188.1 190.5 191.3 189.7 193.2
[1] 188.1 190.5 191.3 189.7 193.2
avg5 <- mean(last5)            # their average
print(round(avg5, 3))          # -> [1] 190.56
[1] 190.56
print(tail(closes, 1) > avg5)  # -> [1] TRUE    <- the latest close sits above the average
[1] TRUE

The same average by position, and then the five closes one place earlier.

print(mean(closes[4:8]))   # -> [1] 190.56    <- same five prices as tail(closes, 5)
[1] 190.56
print(mean(closes[3:7]))   # -> [1] 188.9     <- positions 3 to 7 instead
[1] 188.9

Your turn

Take v <- c(12, 9, 15, 7, 20, 11). Print the second to the fourth elements, then everything except the first, then only the elements above 10, then the mean of the last three.

v <- c(12, 9, 15, 7, 20, 11)

print(v[2:4])              # -> [1]  9 15  7    <- both ends included
print(v[-1])               # -> [1]  9 15  7 20 11    <- the 12 is dropped
print(v[v > 10])           # -> [1] 12 15 20 11
print(round(mean(tail(v, 3)), 2))   # -> [1] 12.67