rep()
rep(x, times = 1, length.out = NA, each = 1) The rep() function replicates the elements of a vector a specified number of times. It is fundamental for creating repeated patterns, expanding datasets, and constructing test data in R.
Syntax
rep(x, times = 1, length.out = NA, each = 1)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
x | vector or list | — | The object to replicate |
times | integer | 1 | Number of times to repeat the entire vector |
length.out | integer | NA | Desired length of the output vector |
each | integer | 1 | Number of times to repeat each element individually |
Examples
Basic usage
# Repeat the entire vector 3 times
rep(c("a", "b"), times = 3)
# [1] "a" "b" "a" "b" "a" "b"
# Repeat each element 2 times
rep(c("a", "b"), each = 2)
# [1] "a" "a" "b" "b"
The times and each arguments control repetition in different ways, but neither guarantees a specific output length — the result depends on the input size and the repetition factor. The length.out argument overrides both and lets you say “give me exactly N elements,” recycling or truncating the pattern as needed to hit the target.
Using length.out
# Specify exact output length (truncates or recycles)
rep(1:3, length.out = 7)
# [1] 1 2 3 1 2 3 1
# Useful for creating equal-length vectors
rep(c("train", "test"), each = 50, length.out = 100)
# Creates 100 labels: 50 train, 50 test
So far each example has used only one argument at a time, but times and each can be combined in a single call. When both are supplied, each is applied first — repeating individual elements — and then times repeats the resulting vector. The interaction follows a predictable left-to-right order that is worth internalizing to avoid surprises when reading other people’s code.
Combining times and each
# Both parameters together
rep(1:2, times = 2, each = 3)
# [1] 1 1 1 2 2 2 1 1 1 2 2 2
Understanding the individual arguments is the foundation, but rep() earns its keep in everyday data work through a handful of recurring patterns. Whether you are assigning experimental groups, generating simulation inputs, or building balanced sampling strata, the same few rep() shapes appear again and again across R scripts.
Common patterns
Creating indicator variables
groups <- rep(c("control", "treatment"), each = 10)
# Creates 20-group assignment vector
Group assignment labels are static, but simulation workflows need to blow up a handful of generated values into thousands of replicates. Using rep() with each is the simplest way to expand a small vector of random draws into a large dataset — each original value gets repeated the specified number of times before the function moves to the next one.
Expanding data for simulation
set.seed(42)
values <- rnorm(5)
repeated <- rep(values, each = 100)
# Each original value repeated 100 times for bootstrap-style analysis
When you need balanced groups rather than block-repeated values, cycling with length.out is the cleaner approach. Instead of calculating how many times to repeat each element, you declare the total desired length and let R figure out the recycling — guaranteeing exactly equal (or off-by-one) group sizes without any manual arithmetic.
Cycling with length.out
# Alternate pattern for stratified sampling
idx <- rep(1:3, length.out = 90)
table(idx)
# idx
# 1 2 3
# 30 30 30
rep() in practice
rep() has two main calling forms: rep(x, times) which repeats the entire vector, and rep(x, each) which repeats each element individually. rep(c(1,2,3), times=2) gives c(1,2,3,1,2,3), while rep(c(1,2,3), each=2) gives c(1,1,2,2,3,3). When times is a vector of the same length as x, each element is repeated the specified number of times: rep(c("a","b","c"), times=c(3,1,2)) gives c("a","a","a","b","c","c").
The length.out argument truncates the output to a specific length. rep(1:3, length.out=7) gives c(1,2,3,1,2,3,1), cycling as needed to reach the target length. This is equivalent to the recycling rule used in vectorized operations, made explicit.
rep_len(x, length.out) is a faster low-level version for the simple cycling case. For creating a vector of a single repeated value, rep(0, n) is slightly slower than the equivalent vector("numeric", n) or numeric(n), since the latter pre-allocates without copying a source vector.
rep() preserves the type of its input: rep(1L, 3) returns an integer vector, rep(1.5, 3) returns a double vector. Names are also repeated: rep(c(a=1, b=2), 2) returns c(a=1, b=2, a=1, b=2) with names intact.
rep() has two main modes: times repeats the entire vector a number of times; each repeats each element before moving to the next. rep(x, times = c(2, 1, 3)) repeats each element a different number of times using a vector for times. rep_len(x, n) is a faster variant that recycles x to exactly length n. Use rep(NA, n) to initialize a vector of missing values and rep(0L, n) for a zero-filled integer vector.
rep() has two main modes. The times argument repeats the entire vector N times: rep(c(1, 2), times = 3) gives c(1, 2, 1, 2, 1, 2). The each argument repeats each element before moving to the next: rep(c(1, 2), each = 3) gives c(1, 1, 1, 2, 2, 2).
When times is a vector the same length as x, each element is repeated a different number of times: rep(c("a", "b", "c"), times = c(2, 1, 3)) gives c("a", "a", "b", "c", "c", "c"). This is useful for constructing lookup or label vectors from counts.
rep_len(x, n) is faster than rep() when you just want to recycle x to a specific length — it avoids the overhead of argument checking. For initializing a vector of known size, rep(0, n) or rep(NA, n) is idiomatic. Use rep(0L, n) for integer storage to save memory compared to the double default.