The apply Family

The apply family is a set of R functions that run a function over each element, row, column, or group of your data — replacing explicit loops with concise, readable one-liners.

Learn The apply Family in our free R course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free R course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

By the end of this lesson you'll use sapply() and lapply() over vectors and lists, apply() over rows and columns of a matrix, and tapply() to summarise values by group.

What You'll Learn in This Lesson

1️⃣ sapply() and lapply()

sapply() applies a function to each element and simplifies the result to a vector when possible. lapply() does the same but always returns a list — predictable when results vary in shape.

2️⃣ apply() over Rows and Columns

apply(X, MARGIN, FUN) runs a function across a matrix or data frame. MARGIN = 1 works on each row; MARGIN = 2 on each column. You can pass a named function or your own.

3️⃣ tapply() for Grouped Summaries

tapply(values, groups, FUN) splits a vector by a grouping vector and applies a function to each group — the base-R way to get "average by category". vapply() is a safer sapply() where you declare the result type.

Your turn. Fill in the # TODO blank, run it, and compare with the expected output.

Write it from the outline, run it, and check it against the example output. tapply() with different functions answers different questions about the same groups.

📋 Quick Reference — apply Family

Practice quiz

What does sapply(c(1, 4, 9), sqrt) return?

  • A list of three values
  • A single number 14
  • A numeric vector c(1, 2, 3)
  • A matrix with one column

Answer: A numeric vector c(1, 2, 3). sapply() simplifies the per-element results to a vector when it can.

How does lapply() differ from sapply()?

  • lapply() always returns a list
  • lapply() only works on matrices
  • lapply() returns a single number
  • lapply() requires a factor argument

Answer: lapply() always returns a list. lapply() always returns a list; sapply() simplifies when possible.

In apply(m, MARGIN, FUN), what does MARGIN = 1 do?

  • Applies FUN to each column
  • Applies FUN to the whole matrix at once
  • Transposes the matrix first
  • Applies FUN to each row

Answer: Applies FUN to each row. MARGIN = 1 means rows; MARGIN = 2 means columns.

Which call gives the maximum of each COLUMN of matrix m?

  • apply(m, 1, max)
  • apply(m, 2, max)
  • sapply(m, max)
  • tapply(m, max)

Answer: apply(m, 2, max). MARGIN = 2 applies the function down each column.

What is tapply(values, groups, FUN) used for?

  • Applying FUN to each group of values defined by a factor
  • Reading a CSV file
  • Transposing a data frame
  • Sorting a vector

Answer: Applying FUN to each group of values defined by a factor. tapply() splits values by group and applies FUN to each group.

How is vapply() safer than sapply()?

  • It runs in parallel automatically
  • It never returns NA
  • You declare the expected result type and length
  • It ignores the function argument

Answer: You declare the expected result type and length. vapply() checks each result against a template like numeric(1).

What does lapply(1:3, function(x) x * 10) return?

  • The vector c(10, 20, 30)
  • A list containing 10, 20, 30
  • The number 60
  • An error

Answer: A list containing 10, 20, 30. lapply() always returns a list, one element per input.

Extra arguments after FUN in sapply(x, round, digits = 2) are...

  • Ignored by sapply()
  • Used as the result type
  • Treated as a second vector to iterate
  • Forwarded to FUN on each call

Answer: Forwarded to FUN on each call. Anything after FUN is passed through to the function.

Why might sapply() return a list instead of a vector?

  • The input was too long
  • The per-element results had differing lengths
  • It was given a factor
  • round() was used

Answer: The per-element results had differing lengths. If results can't be simplified to equal-length pieces, sapply() returns a list.

For tapply() to align correctly, the values and groups vectors must be...

  • Sorted alphabetically
  • Both factors
  • The same length, matched element by element
  • Of length 1

Answer: The same length, matched element by element. Each value pairs with the group at the same position.