1% Generated by roxygen2: do not edit by hand 2% Please edit documentation in R/across.R 3\name{across} 4\alias{across} 5\alias{if_any} 6\alias{if_all} 7\title{Apply a function (or functions) across multiple columns} 8\usage{ 9across(.cols = everything(), .fns = NULL, ..., .names = NULL) 10 11if_any(.cols = everything(), .fns = NULL, ..., .names = NULL) 12 13if_all(.cols = everything(), .fns = NULL, ..., .names = NULL) 14} 15\arguments{ 16\item{.fns}{Functions to apply to each of the selected columns. 17Possible values are: 18\itemize{ 19\item \code{NULL}, to returns the columns untransformed. 20\item A function, e.g. \code{mean}. 21\item A purrr-style lambda, e.g. \code{~ mean(.x, na.rm = TRUE)} 22\item A list of functions/lambdas, e.g. 23\verb{list(mean = mean, n_miss = ~ sum(is.na(.x))} 24} 25 26Within these functions you can use \code{\link[=cur_column]{cur_column()}} and \code{\link[=cur_group]{cur_group()}} 27to access the current column and grouping keys respectively.} 28 29\item{...}{Additional arguments for the function calls in \code{.fns}.} 30 31\item{.names}{A glue specification that describes how to name the output 32columns. This can use \code{{.col}} to stand for the selected column name, and 33\code{{.fn}} to stand for the name of the function being applied. The default 34(\code{NULL}) is equivalent to \code{"{.col}"} for the single function case and 35\code{"{.col}_{.fn}"} for the case where a list is used for \code{.fns}.} 36 37\item{cols, .cols}{<\code{\link[=dplyr_tidy_select]{tidy-select}}> Columns to transform. 38Because \code{across()} is used within functions like \code{summarise()} and 39\code{mutate()}, you can't select or compute upon grouping variables.} 40} 41\value{ 42\code{across()} returns a tibble with one column for each column in \code{.cols} and each function in \code{.fns}. 43 44\code{if_any()} and \code{if_all()} return a logical vector. 45} 46\description{ 47\code{across()} makes it easy to apply the same transformation to multiple 48columns, allowing you to use \code{\link[=select]{select()}} semantics inside in "data-masking" 49functions like \code{\link[=summarise]{summarise()}} and \code{\link[=mutate]{mutate()}}. See \code{vignette("colwise")} for 50more details. 51 52\code{if_any()} and \code{if_all()} apply the same 53predicate function to a selection of columns and combine the 54results into a single logical vector: \code{if_any()} is \code{TRUE} when 55the predicate is \code{TRUE} for \emph{any} of the selected columns, \code{if_all()} 56is \code{TRUE} when the predicate is \code{TRUE} for \emph{all} selected columns. 57 58\code{across()} supersedes the family of "scoped variants" like 59\code{summarise_at()}, \code{summarise_if()}, and \code{summarise_all()}. 60} 61\section{Timing of evaluation}{ 62 63R code in dplyr verbs is generally evaluated once per group. 64Inside \code{across()} however, code is evaluated once for each 65combination of columns and groups. If the evaluation timing is 66important, for example if you're generating random variables, think 67about when it should happen and place your code in consequence.\if{html}{\out{<div class="r">}}\preformatted{gdf <- 68 tibble(g = c(1, 1, 2, 3), v1 = 10:13, v2 = 20:23) \%>\% 69 group_by(g) 70 71set.seed(1) 72 73# Outside: 1 normal variate 74n <- rnorm(1) 75gdf \%>\% mutate(across(v1:v2, ~ .x + n)) 76}\if{html}{\out{</div>}}\preformatted{## # A tibble: 4 x 3 77## # Groups: g [3] 78## g v1 v2 79## <dbl> <dbl> <dbl> 80## 1 1 9.37 19.4 81## 2 1 10.4 20.4 82## 3 2 11.4 21.4 83## 4 3 12.4 22.4 84}\if{html}{\out{<div class="r">}}\preformatted{# Inside a verb: 3 normal variates (ngroup) 85gdf \%>\% mutate(n = rnorm(1), across(v1:v2, ~ .x + n)) 86}\if{html}{\out{</div>}}\preformatted{## # A tibble: 4 x 4 87## # Groups: g [3] 88## g v1 v2 n 89## <dbl> <dbl> <dbl> <dbl> 90## 1 1 10.2 20.2 0.184 91## 2 1 11.2 21.2 0.184 92## 3 2 11.2 21.2 -0.836 93## 4 3 14.6 24.6 1.60 94}\if{html}{\out{<div class="r">}}\preformatted{# Inside `across()`: 6 normal variates (ncol * ngroup) 95gdf \%>\% mutate(across(v1:v2, ~ .x + rnorm(1))) 96}\if{html}{\out{</div>}}\preformatted{## # A tibble: 4 x 3 97## # Groups: g [3] 98## g v1 v2 99## <dbl> <dbl> <dbl> 100## 1 1 10.3 20.7 101## 2 1 11.3 21.7 102## 3 2 11.2 22.6 103## 4 3 13.5 22.7 104} 105} 106 107\examples{ 108# across() ----------------------------------------------------------------- 109# Different ways to select the same set of columns 110# See <https://tidyselect.r-lib.org/articles/syntax.html> for details 111iris \%>\% 112 as_tibble() \%>\% 113 mutate(across(c(Sepal.Length, Sepal.Width), round)) 114iris \%>\% 115 as_tibble() \%>\% 116 mutate(across(c(1, 2), round)) 117iris \%>\% 118 as_tibble() \%>\% 119 mutate(across(1:Sepal.Width, round)) 120iris \%>\% 121 as_tibble() \%>\% 122 mutate(across(where(is.double) & !c(Petal.Length, Petal.Width), round)) 123 124# A purrr-style formula 125iris \%>\% 126 group_by(Species) \%>\% 127 summarise(across(starts_with("Sepal"), ~ mean(.x, na.rm = TRUE))) 128 129# A named list of functions 130iris \%>\% 131 group_by(Species) \%>\% 132 summarise(across(starts_with("Sepal"), list(mean = mean, sd = sd))) 133 134# Use the .names argument to control the output names 135iris \%>\% 136 group_by(Species) \%>\% 137 summarise(across(starts_with("Sepal"), mean, .names = "mean_{.col}")) 138iris \%>\% 139 group_by(Species) \%>\% 140 summarise(across(starts_with("Sepal"), list(mean = mean, sd = sd), .names = "{.col}.{.fn}")) 141 142# When the list is not named, .fn is replaced by the function's position 143iris \%>\% 144 group_by(Species) \%>\% 145 summarise(across(starts_with("Sepal"), list(mean, sd), .names = "{.col}.fn{.fn}")) 146 147# if_any() and if_all() ---------------------------------------------------- 148iris \%>\% 149 filter(if_any(ends_with("Width"), ~ . > 4)) 150iris \%>\% 151 filter(if_all(ends_with("Width"), ~ . > 2)) 152 153} 154\seealso{ 155\code{\link[=c_across]{c_across()}} for a function that returns a vector 156} 157