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"
Those also work:
c(matrix(c(a,b),ncol=3,,T))
c(a,b)[rep(1:length(a),each=2)+c(0,length(a))]
c(mapply(c,a,b))
# [1] "a1" "b1" "a2" "b2" "a3" "b3"
but Ryan's solution is faster:
a <- paste0("a",1:10000)
b <- paste0("b",1:10000)
microbenchmark::microbenchmark(
ryan = c(rbind(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))
)
# Unit: microseconds
# expr min lq mean median uq max neval
# ryan 172.9 192.10 218.366 200.7 222.00 643.5 100
# mm1 258.5 288.10 308.359 300.6 316.05 685.6 100
# mm2 749.9 772.05 787.783 780.9 795.70 1104.6 100
# mm3 9203.0 9585.70 11491.192 9978.7 10209.80 35516.3 100
as.vector
makes it yet a bit faster:
microbenchmark::microbenchmark(
ryan = c(rbind(a,b)),
ryan2 = as.vector(rbind(a,b)))
# Unit: microseconds
# expr min lq mean median uq max neval
# ryan 169.7 185.65 198.797 194.2 208.10 302.0 100
# ryan2 108.8 121.05 135.465 128.3 142.85 297.7 100
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With