15  Vectorized Operations

Many built-in R functions are vectorized and so are many functions from external packages as well.

A vectorized function operates on all elements of an object.

Vectorization is very efficient: it can save both human (your) time and machine time.

In many cases, applying a function on all elements simultaneously may seem like the obvious or expected behavior, but since not all functions are vectorized, make sure to check the documentation (and/or test whether a function is vectorized using a simple example).

15.1 Operations between vectors of equal length

Such operations are applied between corresponding elements of each vector:

x <- 1:10
z <- 11:20
x + z
 [1] 12 14 16 18 20 22 24 26 28 30

i.e. the above is equal to c(x[1] + z[1], x[2] + z[2], ..., x[n] + z[n]).

Weight <- rnorm(20, mean = 80, sd = 1.7)
Weight
 [1] 77.91373 79.86699 80.52305 80.10622 78.14098 83.17635 78.70024 82.12425
 [9] 79.36676 79.74455 81.42692 80.24068 81.88119 81.26264 79.95002 75.42061
[17] 78.89493 79.61213 78.62270 79.58547
Height <- rnorm(20, mean = 1.7, sd = 0.1)
Height
 [1] 1.779991 1.531822 1.910082 1.635881 1.675343 1.607533 1.588977 1.782611
 [9] 1.749316 1.758628 1.647466 1.643699 1.656656 1.706453 1.797082 1.865103
[17] 1.770692 1.671732 1.728966 1.690145
BMI <- Weight/Height^2
BMI
 [1] 24.59111 34.03695 22.07071 29.93385 27.84015 32.18698 31.17029 25.84390
 [9] 25.93595 25.78415 30.00096 29.69958 29.83456 27.90631 24.75614 21.68125
[17] 25.16303 28.48695 26.30118 27.86029

15.2 Operations between a vector and a scalar

In this cases, the scalar is repeated to match the length of the vector, i.e. it is recycled:

x + 10
 [1] 11 12 13 14 15 16 17 18 19 20
x * 2
 [1]  2  4  6  8 10 12 14 16 18 20
x / 10
 [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
x ^ 2
 [1]   1   4   9  16  25  36  49  64  81 100

15.3 Operations between vectors of unequal length: value recycling

Operations between a vector and a scalar are a special case of operations between vectors of unequal length. Whenever you perform an operation between two objects of different length, the shorter object’s elements are recycled:

x + c(2:1)
 [1]  3  3  5  5  7  7  9  9 11 11

Operations between objects of unequal length can occur by mistake. If the shorter object’s length is a multiple of the longer object’s length, there will be no error or warning, as above. Otherwise, there is a warning (which may be confusing at first) BUT recycling still happens and is highly unlikely to be intentional.

x + c(1, 3, 9)
Warning in x + c(1, 3, 9): longer object length is not a multiple of shorter
object length
 [1]  2  5 12  5  8 15  8 11 18 11

15.4 Vectorized matrix operations

Operations between matrices are similarly vectorized, i.e. performed between corresponding elements:

a <- matrix(1:4, nrow = 2)
b <- matrix(11:14, nrow = 2)
a
     [,1] [,2]
[1,]    1    3
[2,]    2    4
b
     [,1] [,2]
[1,]   11   13
[2,]   12   14
a + b
     [,1] [,2]
[1,]   12   16
[2,]   14   18
a * b
     [,1] [,2]
[1,]   11   39
[2,]   24   56
a / b
           [,1]      [,2]
[1,] 0.09090909 0.2307692
[2,] 0.16666667 0.2857143

15.5 Vectorized functions

Some examples of common mathematical operations that are vectorized:

log(x)
 [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379 1.7917595 1.9459101
 [8] 2.0794415 2.1972246 2.3025851
sqrt(x)
 [1] 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490 2.645751 2.828427
 [9] 3.000000 3.162278
sin(x)
 [1]  0.8414710  0.9092974  0.1411200 -0.7568025 -0.9589243 -0.2794155
 [7]  0.6569866  0.9893582  0.4121185 -0.5440211
cos(x)
 [1]  0.5403023 -0.4161468 -0.9899925 -0.6536436  0.2836622  0.9601703
 [7]  0.7539023 -0.1455000 -0.9111303 -0.8390715

15.6 Further study

Optional reading: