Interleaving 2 vectors - simplest solution
I have 2 vectors of equal length that I want to interleave
- First input: 1, 2, 3
- Second input: 4, 5, 6
- Desired output: 1, 4, 2, 5, 3, 6
The simplest base R solution is to rbind()
the 2 inputs and then unravel the matrix.
And when I say “simplest” solution, I mean “thing that is shortest but totally non-obvious”.
v1 <- c(1L, 2L, 3L)
v2 <- c(4L, 5L, 6L)
c(rbind(v1, v2))
[1] 1 4 2 5 3 6
Interleaving 2 vectors - faster solution
Both rbind
and c
copy the data, and copying takes time.
Rather than using c()
to turn the matrix into a vector, you could also just
unset the dim
attribute on the matrix. This will give the same result, but
avoid doing any memory allocation associated with the c
call.
res <- rbind(v1, v2)
attributes(res) <- NULL
res
[1] 1 4 2 5 3 6
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Large-ish example
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
v1 <- v2 <- integer(10000)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Benchmark
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bench_res <- bench::mark(
c(rbind(v1, v2)),
`remove dims` = {
res <- rbind(v1, v2)
attributes(res) <- NULL
res
}
)
expression | median | itr/sec | mem_alloc |
---|---|---|---|
c(rbind(v1, v2)) | 129.2µs | 7523.19 | 156.3KB |
{ | |||
res <- rbind(v1, v2) | |||
attributes(res) <- NULL | |||
res | |||
} 51.8µs 18293.02 78.2KB |
Loading required namespace: tidyr
Summary
- Don’t write a for loop to interleave two vectors of equal length.