Vectors and vectorised operations

R · Essentials · 12 min

Vectorised thinking is the single most important idea for writing correct, fast R.

R has no scalars: 5 is a numeric vector of length one. An atomic vector holds elements of a single type: logical (TRUE/FALSE), integer (5L), double (5, the default for numbers), character ("a") and the rarer complex and raw.

Create vectors with c(1, 2, 3), sequences with 1:10 or seq(0, 1, by = 0.25), and repetitions with rep("a", 3). length(x) gives the size.

Combining different types coerces to the most flexible one: logical < integer < double < character. c(1, "a", TRUE) becomes all character. Check types with typeof() and convert with as.numeric(), as.character() and friends (invalid conversions give NA with a warning).

Arithmetic and comparison are vectorised: x * 2 doubles every element, x > 3 returns a logical vector, and sum, mean, max, cumsum work on whole vectors. When two vectors differ in length, the shorter is recycled: c(1, 2, 3, 4) + c(10, 20) gives 11 22 13 24. Recycling a length-1 vector is everyday R; recycling anything else is usually a bug, and R warns when the lengths don't divide evenly.

sum(x > 3) counts matches and mean(x > 3) gives the proportion, because TRUE counts as 1.

Example

x <- c(4, 8, 15, 16, 23, 42)
print(x * 2)            #> [1]  8 16 30 32 46 84
print(x > 15)           #> [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE
print(sum(x > 15))      #> [1] 3
print(mean(x))          #> [1] 18
print(typeof(1:3))      #> [1] "integer"
print(typeof(c(1, 2)))  #> [1] "double"
print(c(1, "a", TRUE))  #> [1] "1"    "a"    "TRUE"
print(c(1, 2, 3, 4) + c(10, 20))  #> [1] 11 22 13 24
print(seq(0, 1, by = 0.25))       #> [1] 0.00 0.25 0.50 0.75 1.00
print(as.numeric("3.5") + 1)      #> [1] 4.5

Remember

  • Everything is a vector; a single value is a length-1 vector
  • Mixed types coerce: logical < integer < double < character
  • Operations are vectorised and shorter vectors are recycled
  • sum(cond) counts, mean(cond) gives a proportion

Watch out for

  • Relying on recycling with unequal lengths by accident; it silently produces wrong results when lengths divide evenly.

Check yourself

  1. What is c(1, 2, 3, 4) * c(1, 10)?
  2. What type is c(TRUE, 2L, 3.5)?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: cran.r-project.org/doc/manuals/r-release/R-intro.html#Simple-manipulations-numbers-and-vectors