map: Apply a function to each element of a vector

Description Usage Arguments Value See Also Examples

View source: R/map.R

Description

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

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
map(.x, .f, ...)

map_if(.x, .p, .f, ..., .else = NULL)

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

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

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

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

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

map_raw(.x, .f, ...)

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

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

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

map_depth(.x, .depth, .f, ..., .ragged = FALSE)

Arguments

.x

A list or atomic vector.

.f

A function, formula, or vector (not necessarily atomic).

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. If a component is not present, the value of .default will be returned.

...

Additional arguments passed on to the mapped function.

.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.

.else

A function applied to elements of .x for which .p returns FALSE.

.at

A character vector of names, positive numeric vector of positions to include, or a negative numeric vector of positions to exlude. Only those elements corresponding to .at will be modified.

.id

Either a string or NULL. If a string, the output will contain a variable with that name, storing either the name (if .x is named) or the index (if .x is unnamed) of the input. If NULL, the default, no variable will be created.

Only applies to _dfr variant.

.depth

Level of .x to map on. Use a negative value to count up from the lowest level of the list.

  • map_depth(x, 0, fun) is equivalent to fun(x).

  • map_depth(x, 1, fun) is equivalent to x <- map(x, fun)

  • map_depth(x, 2, fun) is equivalent to x <- map(x, ~ map(., fun))

.ragged

If TRUE, will apply to leaves, even if they're not at depth .depth. If FALSE, will throw an error if there are no elements at depth .depth.

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.

If .x has names(), the return value preserves those names.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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))

# The names of the input are preserved in the output:
list(foo = 1, bar = 2) %>% map(`+`, 10)

# Using set_names() with character vectors is handy to keep track
# of the original inputs:
set_names(c("foo", "bar")) %>% map_chr(paste0, ":suffix")

# 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)


# Use a predicate function to decide whether to map a function:
map_if(iris, is.factor, as.character)

# Specify an alternative with the `.else` argument:
map_if(iris, is.factor, as.character, .else = as.integer)

# 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)

# Use `map_depth()` to recursively traverse nested vectors and map
# a function at a certain depth:
x <- list(a = list(foo = 1:2, bar = 3:4), b = list(baz = 5:6))
str(x)
map_depth(x, 2, paste, collapse = "/")

# Equivalent to:
map(x, map, paste, collapse = "/")

tidyverse/purrr documentation built on Jan. 11, 2019, 12:14 p.m.