2.7 Basic Arithmetical Operations on Vectors

R provides a number of arithmetical operations on pairs of numerical vectors. Table 2.2 shows the basic operators.

Table 2.2: Basic arithmetical operations on vectors.
Operation What It Means
x + y addition
x - y subtraction
x * y multiplication
x / y division
x^y exponentiation (raise x to the power y)
x %/% y integer division (quotient after dividing x by y)
x %% y x mod y (remainder after dividing x by y)

The operators are applied element-wise to vectors:

x <- c(10, 15, 20)
y <- c(3, 4, 5)
x + y
## [1] 13 19 25
x - y
## [1]  7 11 15
x * y
## [1]  30  60 100
x / y
## [1] 3.333333 3.750000 4.000000
x^y
## [1]    1000   50625 3200000

As an illustration, the final result is:

\[10^3, 15^4, 20^5.\] The “mod” operator %% can be quite useful. Here is an example: even numbers have a remainder of 0 after division by 2, whereas odd numbers have a remainder of 1. Hence we may use %% to quickly locate the even numbers in a vector, as follows:

vec <- c(2, 7, 9, 12, 15, 24)
vec[vec %% 2 == 0]
## [1]  2 12 24

Recycling applies in vector arithmetic (as in most of R):

vec <- c(2, 7, 9, 12, 15, 24)
2 * vec  # the 2 will be recycled
## [1]  4 14 18 24 30 48
vec + 100 # the 100 will be recycled
## [1] 102 107 109 112 115 124
vec^3  # the 3 will be recycled
## [1]     8   343   729  1728  3375 13824

2.7.1 More Math Functions

You have already met sqrt(). Here are a few more useful math functions involving vectors.

2.7.1.1 Rounding

You can use the round() function to round off numbers to any desired number of decimal places.

roots <- sqrt(1:5)
roots # Too much information!
## [1] 1.000000 1.414214 1.732051 2.000000 2.236068
round(roots, digits = 3) # nicer
## [1] 1.000 1.414 1.732 2.000 2.236

2.7.1.2 Ceiling and Floor

The ceiling() function returns the least integer that is greater than or equal to the given number:

vec <- c(-2.9, -1.1, 0.2, 1.35, 3, 4.01)
ceiling(vec)
## [1] -2 -1  1  2  3  5

The floor() function returns the greatest integer that is less than or equal to the given number:

floor(vec)
## [1] -3 -2  0  1  3  4

2.7.1.3 Vectorization

All of the above operations follow the “vector-in, vector-out” principle—often referred to by R users as vectorization—to which R often adheres. Not only does vectorization permit us to express ideas concisely and in human-readable fashion, but the computations themselves tend to be performed very quickly.

2.7.1.4 Summing and the Mean

There are some functions on vectors that return only a vector of length 1. Among examples we have met so far are:

  • length()
  • any()
  • all()

Another very important function that returns a vector of length 1 is sum() :

vecs <- 1:100
sum(vecs)
## [1] 5050

In statistics we are often interested in the mean of a list of numbers. The mean is defined as:

\[\frac{\text{sum of the numbers}}{\text{how many numbers there are}}\] You can find the mean of a numerical vector as follows:

vec <- c(-3, 4, 17, 23, 51)
meanVec <- sum(vec)/length(vec)

The way we compute the mean in R looks a great deal like its mathematical definition.

You might be interested to know that there is a function in R dedicated to finding the mean. Unsurprisingly, it is called mean() :

mean(vec)
## [1] 18.4

2.7.1.5 Maximum and Minimum

The max() function delivers the maximum value of the elements of a numerical vector:

max(c(3, 7, 2))
## [1] 7

The min() function delivers the minimum value of a numerical vector:

min(c(3, 7, 2))
## [1] 2

You can enter more than one vector into min() or max(): the function will combine the vectors and then do its job:

a <- c(5, 6, 10)
b <- c(2, 3, 12, 15, 1)  # the max of both is 15
max(a, b)
## [1] 15

Both functions yield NA when one of the elements is NA:

max(3, 7, -2, NA)
## [1] NA

Like sum() and mean(), they respond to the na.rm parameter:

max(3, 7, -2, NA, na.rm =TRUE)
## [1] 7

The pmax() function compares corresponding elements of each input-vector and produces a vector of the maximum values:

a <- c(3, 7, 10)
b <- c(5, 2, 12)
pmax(a, b)
## [1]  5  7 12

There is a pmin() function that computes pair-wise minima as well.

2.7.2 NA and NaN Considerations

What happens when you are doing mathematics on a vector, one of whose values is NA? A vectorizing function will simply pass it along:

vec <- c(1, 2, 3, 4, NA)
sqrt(vec)
## [1] 1.000000 1.414214 1.732051 2.000000       NA

On the other hand a function like sum() needs to know all of the values. If one of them is NA, it will report their sum as NA.

sum(vec)
## [1] NA

The same is true for the mean:

mean(vec)
## [1] NA

If we want the sum or the mean of the known values, we could first remove the NA values as demonstrated in previous sections. We could also make use of the na.rm parameter that these functions provide:

sum(vec, na.rm = TRUE)
## [1] 10
mean(vec , na.rm = TRUE)
## [1] 2.5

The results of some arithmetical operations sometimes are not defined. (Examples: you can’t divide by 0; you can’t take the square root of a negative number.) R reports the results of such operations as NaN—“not a number.” R also issues a warning:

sqrt(c(-4, 2, 4))
## Warning in sqrt(c(-4, 2, 4)): NaNs produced
## [1]      NaN 1.414214 2.000000

Keep in mind, though, that the result is a perfectly good vector as far as R is concerned. After the warning R will permit you to use it in further computations:

vec<- sqrt(c(-4, 2, 4))
## Warning in sqrt(c(-4, 2, 4)): NaNs produced
vec + 3
## [1]      NaN 4.414214 5.000000

2.7.3 Practice Exercises

Consider the following vectors:

  1. Write a command that produces the squares of the first 10 whole numbers.

  2. Write a command that produces the square roots of: the numbers from 1 to 100 that are one more than a multiple of 3.

  3. Write a command that raises 2 to the second power, 3 to third power, 4 to the fourth power, … up to 100 to the hundredth power.

  4. Using the sum() function and the vector hasPets from the practice exercises of the previous section, write a command that says how many people have pets.

  5. Using the sum() function and the vector hasPets from the practice exercises of the previous section, write a command that says how many people do not have pets.

  6. Using the vectors from the practice exercises of the previous question, find the name of the person who has the most education.

2.7.4 Solutions to the Practice Exercises

  1. (1:10)^2

  2. Here are a couple of ways:

    sqrt(seq(1, 100, by = 3))
    sqrt((1:100)[1:100 %% 3 == 1])
  3. (2:100)^(2:100)

  4. When given a logical vector, the sum() function converts TRUE to 1 and FALSE to 0, and then adds. Accordingly, you can count how many people have pets like this:

    sum(hasPets)
    ## [1] 3
  5. Do this:

    sum(!hasPets)
    ## [1] 3
  6. Try this:

    person[yearsEducation == max(yearsEducation)]
    ## [1] "Esmeralda"