Learn R Programming

purrr (version 0.2.5)

map: Apply a function to each element of a vector

Description

The map functions transform their input by applying a function to each element and returning a vector the same length as the input.

  • map(), map_if() and map_at() always return a list. See the modify() family for versions that return an object of the same type as the input.

    The _if and _at variants take a predicate function .p that determines which elements of .x are transformed with .f.

  • map_lgl(), map_int(), map_dbl() and map_chr() return vectors of the corresponding type (or die trying).

  • map_dfr() and map_dfc() return data frames created by row-binding and column-binding respectively. They require dplyr to be installed.

  • walk() calls .f for its side-effect and returns the input .x.

Usage

map(.x, .f, ...)

map_if(.x, .p, .f, ...)

map_at(.x, .at, .f, ...)

map_lgl(.x, .f, ...)

map_chr(.x, .f, ...)

map_int(.x, .f, ...)

map_dbl(.x, .f, ...)

map_dfr(.x, .f, ..., .id = NULL)

map_dfc(.x, .f, ...)

walk(.x, .f, ...)

Arguments

.x

A list or atomic vector.

.f

A function, formula, or atomic vector.

If a function, it is used as is.

If a formula, e.g. ~ .x + 2, it is converted to a function. There are three ways to refer to the arguments:

  • For a single argument function, use .

  • For a two argument function, use .x and .y

  • For more arguments, use ..1, ..2, ..3 etc

This syntax allows you to create very compact anonymous functions.

If character vector, numeric vector, or list, it is converted to an extractor function. Character vectors index by name and numeric vectors index by position; use a list to index by position and name at different levels. Within a list, wrap strings in get-attr() to extract named attributes. If a component is not present, the value of .default will be returned.

...

Additional arguments passed on to .f.

.p

A single predicate function, a formula describing such a predicate function, or a logical vector of the same length as .x. Alternatively, if the elements of .x are themselves lists of objects, a string indicating the name of a logical element in the inner lists. Only those elements where .p evaluates to TRUE will be modified.

.at

A character vector of names or a numeric vector of positions. Only those elements corresponding to .at will be modified.

.id

If not NULL a variable with this name will be created giving either the name or the index of the data frame.

Value

All functions return a vector the same length as .x.

map() returns a list, map_lgl() a logical vector, map_int() an integer vector, map_dbl() a double vector, and map_chr() a character vector. The output of .f will be automatically typed upwards, e.g. logical -> integer -> double -> character.

walk() returns the input .x (invisibly). This makes it easy to use in pipe.

See Also

Other map variants: imap, invoke, lmap, map2, modify

Examples

Run this code
# NOT RUN {
1:10 %>%
  map(rnorm, n = 10) %>%
  map_dbl(mean)

# Or use an anonymous function
1:10 %>%
  map(function(x) rnorm(10, x))

# Or a formula
1:10 %>%
  map(~ rnorm(10, .x))

# Extract by name or position
# .default specifies value for elements that are missing or NULL
l1 <- list(list(a = 1L), list(a = NULL, b = 2L), list(b = 3L))
l1 %>% map("a", .default = "???")
l1 %>% map_int("b", .default = NA)
l1 %>% map_int(2, .default = NA)

# Supply multiple values to index deeply into a list
l2 <- list(
  list(num = 1:3,     letters[1:3]),
  list(num = 101:103, letters[4:6]),
  list()
)
l2 %>% map(c(2, 2))

# Use a list to build an extractor that mixes numeric indices and names,
# and .default to provide a default value if the element does not exist
l2 %>% map(list("num", 3))
l2 %>% map_int(list("num", 3), .default = NA)

# A more realistic example: split a data frame into pieces, fit a
# model to each piece, summarise and extract R^2
mtcars %>%
  split(.$cyl) %>%
  map(~ lm(mpg ~ wt, data = .x)) %>%
  map(summary) %>%
  map_dbl("r.squared")

# Use map_lgl(), map_dbl(), etc to reduce to a vector.
# * list
mtcars %>% map(sum)
# * vector
mtcars %>% map_dbl(sum)

# If each element of the output is a data frame, use
# map_dfr to row-bind them together:
mtcars %>%
  split(.$cyl) %>%
  map(~ lm(mpg ~ wt, data = .x)) %>%
  map_dfr(~ as.data.frame(t(as.matrix(coef(.)))))
# (if you also want to preserve the variable names see
# the broom package)
# }

Run the code above in your browser using DataLab