Skip to content
The apply Family in Depth
step 1/5

Reading — step 1 of 5

Learn

~1 min readFunctional Patterns

R has a whole family of *apply functions. Once you internalize them, R code stops needing for loops.

sapply(x, f) — Simplified apply. Returns a vector when possible:

sapply(1:5, function(n) n^2)        # c(1, 4, 9, 16, 25)
sapply(c("hi", "hello"), nchar)    # c(2, 5)

lapply(x, f) — List apply. Always returns a list:

lapply(1:3, function(n) rep(n, n))
# list([1], c(2,2), c(3,3,3))

vapply(x, f, FUN.VALUE) — Like sapply but with a guaranteed return type. Safer for production.

mapply(f, ...) — Multivariate apply. Function takes multiple args:

mapply(function(a, b) a + b, 1:3, 10:12)   # c(11, 13, 15)

apply(matrix, MARGIN, f) — Apply over a matrix's rows or columns:

m <- matrix(1:9, nrow=3)
apply(m, 1, sum)   # row sums: c(12, 15, 18)
apply(m, 2, sum)   # col sums: c(6, 15, 24)

tapply(x, INDEX, f) — Apply f to subsets of x grouped by INDEX:

ages <- c(25, 30, 35, 22, 28)
group <- c("A", "B", "A", "B", "A")
tapply(ages, group, mean)   # A=29.33  B=26

Anonymous function shortcut in R 4.1+: \(x) x * 2 (slash-style). Older R uses function(x) x * 2.

Performance tip: *apply is rarely faster than vectorized ops. Use sum(), mean(), etc. on vectors when you can; reach for apply for genuinely per-element work.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…