#' Repeat a vector
#'
#' @description
#' - `vec_rep()` repeats an entire vector a set number of `times`.
#'
#' - `vec_rep_each()` repeats each element of a vector a set number of `times`.
#'
#' - `vec_unrep()` compresses a vector with repeated values. The repeated values
#' are returned as a `key` alongside the number of `times` each key is
#' repeated.
#'
#' @details
#' Using `vec_unrep()` and `vec_rep_each()` together is similar to using
#' [base::rle()] and [base::inverse.rle()]. The following invariant shows
#' the relationship between the two functions:
#'
#' ```
#' compressed <- vec_unrep(x)
#' identical(x, vec_rep_each(compressed$key, compressed$times))
#' ```
#'
#' There are two main differences between `vec_unrep()` and [base::rle()]:
#'
#' - `vec_unrep()` treats adjacent missing values as equivalent, while `rle()`
#' treats them as different values.
#'
#' - `vec_unrep()` works along the size of `x`, while `rle()` works along its
#' length. This means that `vec_unrep()` works on data frames by compressing
#' repeated rows.
#'
#' @inheritParams rlang::args_error_context
#' @inheritParams rlang::args_dots_empty
#' @param x A vector.
#' @param times
#' For `vec_rep()`, a single integer for the number of times to repeat
#' 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][theory-faq-recycling] to
#' the size of `x`.
#' @param x_arg,times_arg Argument names for errors.
#'
#' @return
#' For `vec_rep()`, a vector the same type as `x` with size
#' `vec_size(x) * times`.
#'
#' For `vec_rep_each()`, a vector the same type as `x` with size
#' `sum(vec_recycle(times, vec_size(x)))`.
#'
#' For `vec_unrep()`, a data frame with two columns, `key` and `times`. `key`
#' is a vector with the same type as `x`, and `times` is an integer vector.
#'
#' @section Dependencies:
#' - [vec_slice()]
#'
#' @name vec-rep
#' @examples
#' # Repeat the entire vector
#' vec_rep(1:2, 3)
#'
#' # Repeat within each vector
#' vec_rep_each(1:2, 3)
#' x <- vec_rep_each(1:2, c(3, 4))
#' x
#'
#' # After using `vec_rep_each()`, you can recover the original vector
#' # with `vec_unrep()`
#' vec_unrep(x)
#'
#' df <- data.frame(x = 1:2, y = 3:4)
#'
#' # `rep()` repeats columns of data frames, and returns lists
#' rep(df, each = 2)
#'
#' # `vec_rep()` and `vec_rep_each()` repeat rows, and return data frames
#' vec_rep(df, 2)
#' vec_rep_each(df, 2)
#'
#' # `rle()` treats adjacent missing values as different
#' y <- c(1, NA, NA, 2)
#' rle(y)
#'
#' # `vec_unrep()` treats them as equivalent
#' vec_unrep(y)
NULL
#' @rdname vec-rep
#' @export
vec_rep <- function(x,
times,
...,
error_call = current_env(),
x_arg = "x",
times_arg = "times") {
check_dots_empty0(...)
.Call(ffi_vec_rep, x, times, environment())
}
#' @rdname vec-rep
#' @export
vec_rep_each <- function(x,
times,
...,
error_call = current_env(),
x_arg = "x",
times_arg = "times") {
check_dots_empty0(...)
.Call(ffi_vec_rep_each, x, times, environment())
}
#' @rdname vec-rep
#' @export
vec_unrep <- function(x) {
.Call(ffi_vec_unrep, x, environment())
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.