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