% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/map.R
\name{map}
\alias{map}
\alias{map_lgl}
\alias{map_int}
\alias{map_dbl}
\alias{map_chr}
\alias{map_vec}
\alias{walk}
\title{Apply a function to each element of a vector}
\usage{
map(.x, .f, ..., .progress = FALSE)

map_lgl(.x, .f, ..., .progress = FALSE)

map_int(.x, .f, ..., .progress = FALSE)

map_dbl(.x, .f, ..., .progress = FALSE)

map_chr(.x, .f, ..., .progress = FALSE)

map_vec(.x, .f, ..., .ptype = NULL, .progress = FALSE)

walk(.x, .f, ..., .progress = FALSE)
}
\arguments{
\item{.x}{A list or atomic vector.}

\item{.f}{A function, specified in one of the following ways:
\itemize{
\item A named function, e.g. \code{mean}.
\item An anonymous function, e.g. \verb{\\(x) x + 1} or \code{function(x) x + 1}.
\item A formula, e.g. \code{~ .x + 1}. Use \code{.x} to refer to the first
argument. No longer recommended.
\item A string, integer, or list, e.g. \code{"idx"}, \code{1}, or \code{list("idx", 1)} which
are shorthand for \verb{\\(x) pluck(x, "idx")}, \verb{\\(x) pluck(x, 1)}, and
\verb{\\(x) pluck(x, "idx", 1)} respectively. Optionally supply \code{.default} to
set a default value if the indexed element is \code{NULL} or does not exist.
}

\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}}

Wrap a function with \code{\link[=in_parallel]{in_parallel()}} to declare that it should be performed
in parallel. See \code{\link[=in_parallel]{in_parallel()}} for more details.
Use of \code{...} is not permitted in this context.}

\item{...}{Additional arguments passed on to the mapped function.

We now generally recommend against using \code{...} to pass additional
(constant) arguments to \code{.f}. Instead use a shorthand anonymous function:

\if{html}{\out{<div class="sourceCode R">}}\preformatted{# Instead of
x |> map(f, 1, 2, collapse = ",")
# do:
x |> map(\\(x) f(x, 1, 2, collapse = ","))
}\if{html}{\out{</div>}}

This makes it easier to understand which arguments belong to which
function and will tend to yield better error messages.}

\item{.progress}{Whether to show a progress bar. Use \code{TRUE} to turn on
a basic progress bar, use a string to give it a name, or see
\link{progress_bars} for more details.}

\item{.ptype}{If \code{NULL}, the default, the output type is the common type
of the elements of the result. Otherwise, supply a "prototype" giving
the desired type of output.}
}
\value{
The output length is determined by the length of the input.
The output names are determined by the input names.
The output type is determined by the suffix:
\itemize{
\item No suffix: a list; \code{.f()} can return anything.
\item \verb{_lgl()}, \verb{_int()}, \verb{_dbl()}, \verb{_chr()} return a logical, integer, double,
or character vector respectively; \code{.f()} must return a compatible atomic
vector of length 1.
\item \verb{_vec()} return an atomic or S3 vector, the same type that \code{.f} returns.
\code{.f} can return pretty much any type of vector, as long as its length 1.
\item \code{walk()} returns the input \code{.x} (invisibly). This makes it easy to
use in a pipe. The return value of \code{.f()} is ignored.
}

Any errors thrown by \code{.f} will be wrapped in an error with class
\link{purrr_error_indexed}.
}
\description{
The map functions transform their input by applying a function to
each element of a list or atomic vector and returning an object of
the same length as the input.
\itemize{
\item \code{map()} always returns a list. See the \code{\link[=modify]{modify()}} family for
versions that return an object of the same type as the input.
\item \code{map_lgl()}, \code{map_int()}, \code{map_dbl()} and \code{map_chr()} return an
atomic vector of the indicated type (or die trying). For these functions,
\code{.f} must return a length-1 vector of the appropriate type.
\item \code{map_vec()} simplifies to the common type of the output. It works with
most types of simple vectors like Date, POSIXct, factors, etc.
\item \code{walk()} calls \code{.f} for its side-effect and returns
the input \code{.x}.
}
}
\examples{
# Compute normal distributions from an atomic vector
1:10 |>
  map(rnorm, n = 10)

# You can also use an anonymous function
1:10 |>
  map(\(x) rnorm(10, x))

# Simplify output to a vector instead of a list by computing the mean of the distributions
1:10 |>
  map(rnorm, n = 10) |>  # output a list
  map_dbl(mean)           # output an atomic vector

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

# Working with lists
favorite_desserts <- list(Sophia = "banana bread", Eliott = "pancakes", Karina = "chocolate cake")
favorite_desserts |> map_chr(\(food) paste(food, "rocks!"))

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

# Working with data frames
# Use map_lgl(), map_dbl(), etc to return a vector instead of a list:
mtcars |> map_dbl(sum)

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

\dontshow{if (interactive() && rlang::is_installed("mirai") && rlang::is_installed("carrier")) withAutoprint(\{ # examplesIf}
# Run in interactive sessions only as spawns additional processes

# To use parallelized map:
# 1. Set daemons (number of parallel processes) first:
mirai::daemons(2)

# 2. Wrap .f with in_parallel():
mtcars |> map_dbl(in_parallel(\(x) mean(x)))

# Note that functions from packages should be fully qualified with `pkg::`
# or call `library(pkg)` within the function
1:10 |>
  map(in_parallel(\(x) vctrs::vec_init(integer(), x))) |>
  map_int(in_parallel(\(x) { library(vctrs); vec_size(x) }))

# A locally-defined function (or any required variables)
# should be passed via ... of in_parallel():
slow_lm <- function(formula, data) {
  Sys.sleep(0.5)
  lm(formula, data)
}

mtcars |>
  split(mtcars$cyl) |>
  map(in_parallel(\(df) slow_lm(mpg ~ disp, data = df), slow_lm = slow_lm))

# Tear down daemons when no longer in use:
mirai::daemons(0)
\dontshow{\}) # examplesIf}
}
\seealso{
\code{\link[=map_if]{map_if()}} for applying a function to only those elements
of \code{.x} that meet a specified condition.

Other map variants: 
\code{\link{imap}()},
\code{\link{lmap}()},
\code{\link{map2}()},
\code{\link{map_depth}()},
\code{\link{map_if}()},
\code{\link{modify}()},
\code{\link{pmap}()}
}
\concept{map variants}
