diff --git a/R/bind.R b/R/bind.R index 45a1b295b..296a689e3 100644 --- a/R/bind.R +++ b/R/bind.R @@ -187,7 +187,7 @@ vec_rbind <- fn_inline_formals(vec_rbind, ".name_repair") #' @rdname vec_bind #' @param .size If, `NULL`, the default, will determine the number of rows in #' `vec_cbind()` output by using the tidyverse [recycling -#' rules][vector_recycling_rules]. +#' rules][theory-faq-recycling]. #' #' Alternatively, specify the desired number of rows, and any inputs of length #' 1 will be recycled appropriately. diff --git a/R/faq-developer.R b/R/faq-developer.R index b1fc0c98e..b9f2ec6b3 100644 --- a/R/faq-developer.R +++ b/R/faq-developer.R @@ -12,6 +12,17 @@ NULL #' @name theory-faq-coercion NULL +# Also see the `redirects:` section in `_pkgdown.yml` +# for `vector_recycling_rules.html` + +#' FAQ - How does recycling work in vctrs and the tidyverse? +#' +#' @includeRmd man/faq/developer/theory-recycling.Rmd description +#' +#' @name theory-faq-recycling +#' @aliases vector_recycling_rules +NULL + #' FAQ - How to implement ptype2 and cast methods? #' #' @includeRmd man/faq/developer/howto-coercion.Rmd description diff --git a/R/recycle.R b/R/recycle.R index d7e7bbf93..6c8a69fe7 100644 --- a/R/recycle.R +++ b/R/recycle.R @@ -1,80 +1,8 @@ -#' Recycling rules used by r-lib and the tidyverse -#' -#' @description -#' Recycling describes the concept of repeating elements of one vector to match -#' the size of another. There are two rules that underlie the "tidyverse" -#' recycling rules: -#' -#' - Vectors of size 1 will be recycled to the size of any other vector -#' -#' - Otherwise, all vectors must have the same size -#' -#' @section Examples: -#' -#' ```{r, warning = FALSE, message = FALSE, include = FALSE} -#' library(tibble) -#' ``` -#' -#' Vectors of size 1 are recycled to the size of any other vector: -#' -#' ```{r, comment = "#>"} -#' tibble(x = 1:3, y = 1L) -#' ``` -#' -#' This includes vectors of size 0: -#' -#' ```{r, comment = "#>"} -#' tibble(x = integer(), y = 1L) -#' ``` -#' -#' If vectors aren't size 1, they must all be the same size. Otherwise, an error -#' is thrown: -#' -#' ```{r, comment = "#>", error = TRUE} -#' tibble(x = 1:3, y = 4:7) -#' ``` -#' -#' @section vctrs backend: -#' -#' Packages in r-lib and the tidyverse generally use [vec_size_common()] and -#' [vec_recycle_common()] as the backends for handling recycling rules. -#' -#' - `vec_size_common()` returns the common size of multiple vectors, after -#' applying the recycling rules -#' -#' - `vec_recycle_common()` goes one step further, and actually recycles the -#' vectors to their common size -#' -#' ```{r, comment = "#>", error = TRUE} -#' vec_size_common(1:3, "x") -#' -#' vec_recycle_common(1:3, "x") -#' -#' vec_size_common(1:3, c("x", "y")) -#' ``` -#' -#' @section Base R recycling rules: -#' -#' The recycling rules described here are stricter than the ones generally used -#' by base R, which are: -#' -#' - If any vector is length 0, the output will be length 0 -#' -#' - Otherwise, the output will be length `max(length_x, length_y)`, and a -#' warning will be thrown if the length of the longer vector is not an integer -#' multiple of the length of the shorter vector. -#' -#' We explore the base R rules in detail in `vignette("type-size")`. -#' -#' @name vector_recycling_rules -#' @keywords internal -NULL - #' Vector recycling #' #' `vec_recycle(x, size)` recycles a single vector to a given size. #' `vec_recycle_common(...)` recycles multiple vectors to their common size. All -#' functions obey the [vctrs recycling rules][vector_recycling_rules], and will +#' functions obey the [vctrs recycling rules][theory-faq-recycling], and will #' throw an error if recycling is not possible. See [vec_size()] for the precise #' definition of size. #' diff --git a/R/rep.R b/R/rep.R index ac08a1719..7ff9b1003 100644 --- a/R/rep.R +++ b/R/rep.R @@ -36,7 +36,7 @@ #' the entire vector. #' #' For `vec_rep_each()`, an integer vector of the number of times to repeat -#' each element of `x`. `times` will be [recycled][vector_recycling_rules] to +#' each element of `x`. `times` will be [recycled][theory-faq-recycling] to #' the size of `x`. #' @param x_arg,times_arg Argument names for errors. #' diff --git a/R/size.R b/R/size.R index 1ee03f75e..46d287c5c 100644 --- a/R/size.R +++ b/R/size.R @@ -19,7 +19,7 @@ #' to `vec_size()` as [lengths()] is to [length()]. #' #' @seealso [vec_slice()] for a variation of `[` compatible with `vec_size()`, -#' and [vec_recycle()] to [recycle][vector_recycling_rules] vectors to common +#' and [vec_recycle()] to [recycle][theory-faq-recycling] vectors to common #' length. #' @section Invariants: #' * `vec_size(dataframe)` == `vec_size(dataframe[[i]])` diff --git a/R/slice-interleave.R b/R/slice-interleave.R index dd26557ac..0ebf91e95 100644 --- a/R/slice-interleave.R +++ b/R/slice-interleave.R @@ -20,7 +20,7 @@ #' @inheritParams vec_c #' #' @param ... Vectors to interleave. These will be -#' [recycled][vector_recycling_rules] to a common size. +#' [recycled][theory-faq-recycling] to a common size. #' #' @export #' @examples diff --git a/R/type-data-frame.R b/R/type-data-frame.R index 12d29cbbd..b06b3a371 100644 --- a/R/type-data-frame.R +++ b/R/type-data-frame.R @@ -39,7 +39,7 @@ new_data_frame <- fn_inline_formals(new_data_frame, "x") #' #' @section Properties: #' -#' - Inputs are [recycled][vector_recycling_rules] to a common size with +#' - Inputs are [recycled][theory-faq-recycling] to a common size with #' [vec_recycle_common()]. #' #' - With the exception of data frames, inputs are not modified in any way. diff --git a/_pkgdown.yml b/_pkgdown.yml index 812117b9f..6f4073c2a 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -131,3 +131,10 @@ reference: - vec_names - vec_as_location - vec_as_subscript + +# Needed to generate a `vector_recycling_rules` page, since it is an `@alias` +# but pkgdown doesn't currently generate pages for aliases. Other packages +# link to this old page name, so we don't want it to disappear. +# https://github.com/r-lib/pkgdown/issues/1876 +redirects: + - ["reference/vector_recycling_rules.html", "reference/theory-faq-recycling.html"] diff --git a/man/data_frame.Rd b/man/data_frame.Rd index 36fae58e7..334e30679 100644 --- a/man/data_frame.Rd +++ b/man/data_frame.Rd @@ -44,7 +44,7 @@ repair for convenience and performance. \section{Properties}{ \itemize{ -\item Inputs are \link[=vector_recycling_rules]{recycled} to a common size with +\item Inputs are \link[=theory-faq-recycling]{recycled} to a common size with \code{\link[=vec_recycle_common]{vec_recycle_common()}}. \item With the exception of data frames, inputs are not modified in any way. Character vectors are never converted to factors, and lists are stored diff --git a/man/df_list.Rd b/man/df_list.Rd index 91f6f2ae3..1ea4117f9 100644 --- a/man/df_list.Rd +++ b/man/df_list.Rd @@ -41,7 +41,7 @@ a helper function for data frame subclasses. \section{Properties}{ \itemize{ -\item Inputs are \link[=vector_recycling_rules]{recycled} to a common size with +\item Inputs are \link[=theory-faq-recycling]{recycled} to a common size with \code{\link[=vec_recycle_common]{vec_recycle_common()}}. \item With the exception of data frames, inputs are not modified in any way. Character vectors are never converted to factors, and lists are stored diff --git a/man/faq/developer/theory-recycling.Rmd b/man/faq/developer/theory-recycling.Rmd new file mode 100644 index 000000000..14046cf98 --- /dev/null +++ b/man/faq/developer/theory-recycling.Rmd @@ -0,0 +1,59 @@ + +```{r, child = "../setup.Rmd", include = FALSE} +``` + +Recycling describes the concept of repeating elements of one vector to match the size of another. There are two rules that underlie the "tidyverse" recycling rules: + +- Vectors of size 1 will be recycled to the size of any other vector + +- Otherwise, all vectors must have the same size + +# Examples + +```{r, warning = FALSE, message = FALSE, include = FALSE} +library(tibble) +``` + +Vectors of size 1 are recycled to the size of any other vector: + +```{r} +tibble(x = 1:3, y = 1L) +``` + +This includes vectors of size 0: + +```{r} +tibble(x = integer(), y = 1L) +``` + +If vectors aren't size 1, they must all be the same size. Otherwise, an error is thrown: + +```{r, error = TRUE} +tibble(x = 1:3, y = 4:7) +``` + +# vctrs backend + +Packages in r-lib and the tidyverse generally use [vec_size_common()] and [vec_recycle_common()] as the backends for handling recycling rules. + +- `vec_size_common()` returns the common size of multiple vectors, after applying the recycling rules + +- `vec_recycle_common()` goes one step further, and actually recycles the vectors to their common size + +```{r, error = TRUE} +vec_size_common(1:3, "x") + +vec_recycle_common(1:3, "x") + +vec_size_common(1:3, c("x", "y")) +``` + +# Base R recycling rules + +The recycling rules described here are stricter than the ones generally used by base R, which are: + +- If any vector is length 0, the output will be length 0 + +- Otherwise, the output will be length `max(length_x, length_y)`, and a warning will be thrown if the length of the longer vector is not an integer multiple of the length of the shorter vector. + +We explore the base R rules in detail in `vignette("type-size")`. diff --git a/man/vector_recycling_rules.Rd b/man/theory-faq-recycling.Rd similarity index 75% rename from man/vector_recycling_rules.Rd rename to man/theory-faq-recycling.Rd index b922747e9..a4f9f6961 100644 --- a/man/vector_recycling_rules.Rd +++ b/man/theory-faq-recycling.Rd @@ -1,20 +1,19 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/recycle.R -\name{vector_recycling_rules} +% Please edit documentation in R/faq-developer.R +\name{theory-faq-recycling} +\alias{theory-faq-recycling} \alias{vector_recycling_rules} -\title{Recycling rules used by r-lib and the tidyverse} +\title{FAQ - How does recycling work in vctrs and the tidyverse?} \description{ -Recycling describes the concept of repeating elements of one vector to match -the size of another. There are two rules that underlie the "tidyverse" -recycling rules: +Recycling describes the concept of repeating elements of one vector to +match the size of another. There are two rules that underlie the +“tidyverse” recycling rules: \itemize{ \item Vectors of size 1 will be recycled to the size of any other vector \item Otherwise, all vectors must have the same size } } \section{Examples}{ - - Vectors of size 1 are recycled to the size of any other vector: \if{html}{\out{