Interleaving vectors and matrices (part 1)

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
}
)``````
Table 1: bench::mark() comparing interleaving methods. Removing attributes saves on memory allocation and is therefore much faster than `c()`
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.