The apply family is idiomatic R for transforming lists, columns and grouped data.
The apply functions call a function on each element and collect the results:
lapply(x, f)always returns a list the same length asx.sapply(x, f)tries to simplify the result to a vector or matrix. Convenient interactively, but its output type depends on the data (an empty input giveslist()), so avoid it in functions.vapply(x, f, FUN.VALUE = numeric(1))declares the type and length of each result and errors otherwise: the safe choice in code.Map(f, x, y)(ormapply) walks several vectors in parallel.apply(m, 1, f)applies over matrix rows (2for columns);tapply(x, group, f)applies within groups.Filter(pred, x)andReduce(f, x)complete the functional toolkit.
Because a data frame is a list of columns, lapply(df, class) or vapply(df, is.numeric, logical(1)) operate column by column.
Extra arguments after the function are passed through: lapply(lst, mean, na.rm = TRUE). Anonymous functions are natural here, especially with the \(x) shorthand.
These functions are not dramatically faster than a well-written loop; their benefit is clarity and no manual result bookkeeping. The purrr package offers a consistent typed family (map, map_dbl, map2) used widely in tidyverse code.
Example
scores <- list(ana = c(90, 85, NA), bo = c(70, 75), cy = numeric(0))
print(lapply(scores, length)$bo) #> [1] 2
print(sapply(scores, mean, na.rm = TRUE))
#> ana bo cy
#> 87.5 72.5 NaN
print(vapply(scores, \(s) sum(!is.na(s)), numeric(1)))
#> ana bo cy
#> 2 2 0
print(class(sapply(list(), length))) #> [1] "list" (!)
print(unlist(Map(\(n, s) paste(n, max(s)), c("a", "b"), list(1:3, 4:6))))
#> a b
#> "a 3" "b 6"
print(Reduce(`+`, 1:5, accumulate = TRUE)) #> [1] 1 3 6 10 15
print(vapply(mtcars[1:3], is.numeric, logical(1)))
#> mpg cyl disp
#> TRUE TRUE TRUERemember
lapplyreturns a list, always- Prefer
vapplywith a declared result type inside functions Mapiterates several inputs in parallel- A data frame is a list, so these work column-wise
Watch out for
- Using sapply in package code, whose return type changes with the input.