Suppose I have two vectors defined as follows:
a <- c("a1", "a2", "a3")
b <- c("b1", "b2", "b3")
Now I want to end up with a string vector like this one:
c("a1","b1", "a2", "b2", "a3", "b3")
Is this possible?
You can rbind
them, then coerce back to a vector.
a <- c("a1", "a2", "a3")
b <- c("b1", "b2", "b3")
c(rbind(a,b))
# [1] "a1" "b1" "a2" "b2" "a3" "b3"
As @Moody_Mudskipper points out, as.vector(rbind(a,b)))
is faster
For the case when the lengths are different, I found the following solution from Rolf Turner at this link: http://r.789695.n4.nabble.com/Interleaving-elements-of-two-vectors-td795123.html
riffle <- function (a,b) {
n <- min(length(a),length(b))
p1 <- as.vector(rbind(a[1:n],b[1:n]))
p2 <- c(a[-(1:n)],b[-(1:n)])
c(p1,p2)
}
riffle(1:3, letters[1:5])
# [1] "1" "a" "2" "b" "3" "c" "d" "e"
There is also vctrs::vec_interleave()
a <- paste0("a", seq(1e6))
b <- paste0("b", seq(1e6))
bench::mark(
rbind = as.vector(rbind(a,b)),
vec_interleave = vctrs::vec_interleave(a, b),
mm1 = c(matrix(c(a,b),ncol=length(a),,T)),
mm2 = c(a,b)[rep(1:length(a),each=2)+c(0,length(a))],
mm3 = c(mapply(c,a,b)),
)
#> Warning: Some expressions had a GC in every iteration; so filtering is disabled.
#> # A tibble: 5 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 rbind 22ms 57.6ms 21.9 30.5MB 11.9
#> 2 vec_interleave 33.6ms 35.1ms 13.1 22.9MB 3.75
#> 3 mm1 61.7ms 70.2ms 12.8 45.8MB 5.48
#> 4 mm2 68.8ms 103.7ms 9.98 64.8MB 8.32
#> 5 mm3 884.3ms 884.3ms 1.13 69MB 3.39
Created on 2023-11-24 with reprex v2.0.2