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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/group-map.R
\name{group_map}
\alias{group_map}
\alias{group_modify}
\alias{group_walk}
\title{Apply a function to each group}
\usage{
group_map(.data, .f, ..., .keep = FALSE)
group_modify(.data, .f, ..., .keep = FALSE)
group_walk(.data, .f, ..., .keep = FALSE)
}
\arguments{
\item{.data}{A grouped tibble}
\item{.f}{A function or formula to apply to each group.
If a \strong{function}, it is used as is. It should have at least 2 formal arguments.
If a \strong{formula}, e.g. \code{~ head(.x)}, it is converted to a function.
In the formula, you can use
\itemize{
\item \code{.} or \code{.x} to refer to the subset of rows of \code{.tbl}
for the given group
\item \code{.y} to refer to the key, a one row tibble with one column per grouping variable
that identifies the group
}}
\item{...}{Additional arguments passed on to \code{.f}}
\item{.keep}{are the grouping variables kept in \code{.x}}
}
\value{
\itemize{
\item \code{group_modify()} returns a grouped tibble. In that case \code{.f} must return a data frame.
\item \code{group_map()} returns a list of results from calling \code{.f} on each group.
\item \code{group_walk()} calls \code{.f} for side effects and returns the input \code{.tbl}, invisibly.
}
}
\description{
\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}}
\code{group_map()}, \code{group_modify()} and \code{group_walk()} are purrr-style functions that can
be used to iterate on grouped tibbles.
}
\details{
Use \code{group_modify()} when \code{summarize()} is too limited, in terms of what you need
to do and return for each group. \code{group_modify()} is good for "data frame in, data frame out".
If that is too limited, you need to use a \link[=group_nest]{nested} or \link[=group_split]{split} workflow.
\code{group_modify()} is an evolution of \code{\link[=do]{do()}}, if you have used that before.
Each conceptual group of the data frame is exposed to the function \code{.f} with two pieces of information:
\itemize{
\item The subset of the data for the group, exposed as \code{.x}.
\item The key, a tibble with exactly one row and columns for each grouping variable, exposed as \code{.y}.
}
For completeness, \code{group_modify()}, \code{group_map} and \code{group_walk()} also work on
ungrouped data frames, in that case the function is applied to the
entire data frame (exposed as \code{.x}), and \code{.y} is a one row tibble with no
column, consistently with \code{\link[=group_keys]{group_keys()}}.
}
\examples{
# return a list
mtcars \%>\%
group_by(cyl) \%>\%
group_map(~ head(.x, 2L))
# return a tibble grouped by `cyl` with 2 rows per group
# the grouping data is recalculated
mtcars \%>\%
group_by(cyl) \%>\%
group_modify(~ head(.x, 2L))
\dontshow{if (requireNamespace("broom", quietly = TRUE)) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
# a list of tibbles
iris \%>\%
group_by(Species) \%>\%
group_map(~ broom::tidy(lm(Petal.Length ~ Sepal.Length, data = .x)))
# a restructured grouped tibble
iris \%>\%
group_by(Species) \%>\%
group_modify(~ broom::tidy(lm(Petal.Length ~ Sepal.Length, data = .x)))
\dontshow{\}) # examplesIf}
# a list of vectors
iris \%>\%
group_by(Species) \%>\%
group_map(~ quantile(.x$Petal.Length, probs = c(0.25, 0.5, 0.75)))
# to use group_modify() the lambda must return a data frame
iris \%>\%
group_by(Species) \%>\%
group_modify(~ {
quantile(.x$Petal.Length, probs = c(0.25, 0.5, 0.75)) \%>\%
tibble::enframe(name = "prob", value = "quantile")
})
iris \%>\%
group_by(Species) \%>\%
group_modify(~ {
.x \%>\%
purrr::map_dfc(fivenum) \%>\%
mutate(nms = c("min", "Q1", "median", "Q3", "max"))
})
# group_walk() is for side effects
dir.create(temp <- tempfile())
iris \%>\%
group_by(Species) \%>\%
group_walk(~ write.csv(.x, file = file.path(temp, paste0(.y$Species, ".csv"))))
list.files(temp, pattern = "csv$")
unlink(temp, recursive = TRUE)
# group_modify() and ungrouped data frames
mtcars \%>\%
group_modify(~ head(.x, 2L))
}
\seealso{
Other grouping functions:
\code{\link{group_by}()},
\code{\link{group_nest}()},
\code{\link{group_split}()},
\code{\link{group_trim}()}
}
\concept{grouping functions}
|