rguides

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

ParameterTypeDefaultDescription
xvector or listThe object to replicate
timesinteger1Number of times to repeat the entire vector
length.outintegerNADesired length of the output vector
eachinteger1Number 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.

See also