3.4 Apply Family

Apply family is a very convenient tools to loop over data structure (vector, array, matrix and list). The most useful for our purposes are:

  1. apply(),
  2. sapply(), and
  3. lapply().

3.4.1 apply

We will to apply a function to each row or each column on a matrix. It will apply a function by-column (=2) or by-row (=1). The following example calculates the mean of each row or each column using the function mean:

m <- matrix(1:9, nrow = 3, ncol=3)
m
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
apply(m,1,mean) # average each row
## [1] 4 5 6
apply(m,2,mean) # average each column
## [1] 2 5 8

You may also use any other custome functions. For example, the following is a function that retun the sum of even entries.

evensum <- function (x){
  sum <- 0
  for (i in 1:length(x)){
    if (i %% 2 == 0){
      sum <- sum + x[i]
    }
  }
  return(sum)
}

Let us see how this function work on the vector 1:4. The sum of the second and forth entries gives the value 6.

evensum(1:4)
## [1] 6

Now we use the apply function:

m <- matrix(1:16, nrow = 4, ncol=4)
m
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    2    6   10   14
## [3,]    3    7   11   15
## [4,]    4    8   12   16
apply(m,1,evensum) # each row
## [1] 18 20 22 24
apply(m,2,evensum) # each column
## [1]  6 14 22 30

3.4.2 sapply and lapply

Sometimes, we will apply a function repeatedly on each element of a vector (or a list). Then sapply is more convenient then a for loop.

Consider the following for loop that returns the square of each element

x <- c(1,3,5)
for (i in 1:length(x)) {
  x[i] <- x[i]^2
}
x
## [1]  1  9 25

We can do the same using sapply() with much cleaner code.

f <- function (x) x^2
x <- c(1,3,5)
x <- sapply(x, f)
x
## [1]  1  9 25

We can even put the function inside sapply:

x <- c(1,3,5)
x <- sapply(x, function(x) x^2)
x
## [1]  1  9 25

lapply() is the same as sapply() but we end up with a list instead of vector. We can use unlist to get back the same result as sapply().

x <- c(1,3,5)
x <- lapply(x, function(x) x^2)
x
## [[1]]
## [1] 1
## 
## [[2]]
## [1] 9
## 
## [[3]]
## [1] 25
x <- unlist(x)
x
## [1]  1  9 25