1#' Repeat a vector 2#' 3#' @description 4#' - `vec_rep()` repeats an entire vector a set number of `times`. 5#' 6#' - `vec_rep_each()` repeats each element of a vector a set number of `times`. 7#' 8#' - `vec_unrep()` compresses a vector with repeated values. The repeated values 9#' are returned as a `key` alongside the number of `times` each key is 10#' repeated. 11#' 12#' @details 13#' Using `vec_unrep()` and `vec_rep_each()` together is similar to using 14#' [base::rle()] and [base::inverse.rle()]. The following invariant shows 15#' the relationship between the two functions: 16#' 17#' ``` 18#' compressed <- vec_unrep(x) 19#' identical(x, vec_rep_each(compressed$key, compressed$times)) 20#' ``` 21#' 22#' There are two main differences between `vec_unrep()` and [base::rle()]: 23#' 24#' - `vec_unrep()` treats adjacent missing values as equivalent, while `rle()` 25#' treats them as different values. 26#' 27#' - `vec_unrep()` works along the size of `x`, while `rle()` works along its 28#' length. This means that `vec_unrep()` works on data frames by compressing 29#' repeated rows. 30#' 31#' @param x A vector. 32#' @param times 33#' For `vec_rep()`, a single integer for the number of times to repeat 34#' the entire vector. 35#' 36#' For `vec_rep_each()`, an integer vector of the number of times to repeat 37#' each element of `x`. `times` will be recycled to the size of `x`. 38#' 39#' @return 40#' For `vec_rep()`, a vector the same type as `x` with size 41#' `vec_size(x) * times`. 42#' 43#' For `vec_rep_each()`, a vector the same type as `x` with size 44#' `sum(vec_recycle(times, vec_size(x)))`. 45#' 46#' For `vec_unrep()`, a data frame with two columns, `key` and `times`. `key` 47#' is a vector with the same type as `x`, and `times` is an integer vector. 48#' 49#' @section Dependencies: 50#' - [vec_slice()] 51#' 52#' @name vec-rep 53#' @examples 54#' # Repeat the entire vector 55#' vec_rep(1:2, 3) 56#' 57#' # Repeat within each vector 58#' vec_rep_each(1:2, 3) 59#' x <- vec_rep_each(1:2, c(3, 4)) 60#' x 61#' 62#' # After using `vec_rep_each()`, you can recover the original vector 63#' # with `vec_unrep()` 64#' vec_unrep(x) 65#' 66#' df <- data.frame(x = 1:2, y = 3:4) 67#' 68#' # `rep()` repeats columns of data frames, and returns lists 69#' rep(df, each = 2) 70#' 71#' # `vec_rep()` and `vec_rep_each()` repeat rows, and return data frames 72#' vec_rep(df, 2) 73#' vec_rep_each(df, 2) 74#' 75#' # `rle()` treats adjacent missing values as different 76#' y <- c(1, NA, NA, 2) 77#' rle(y) 78#' 79#' # `vec_unrep()` treats them as equivalent 80#' vec_unrep(y) 81NULL 82 83#' @rdname vec-rep 84#' @export 85vec_rep <- function(x, times) { 86 .Call(vctrs_rep, x, times) 87} 88 89#' @rdname vec-rep 90#' @export 91vec_rep_each <- function(x, times) { 92 .Call(vctrs_rep_each, x, times) 93} 94 95#' @rdname vec-rep 96#' @export 97vec_unrep <- function(x) { 98 .Call(vctrs_unrep, x) 99} 100