19

I want to interlace two vectors of same mode and equal length. Say:

a <- rpois(lambda=3,n=5e5)
b <- rpois(lambda=4,n=5e5)

I would like to interweave or interlace these two vectors, to create a vector that would be equivalently c(a[1],b[1],a[2],b[2],...,a[length(a)],b[length(b)])

My first attempt was this:

sapply(X=rep.int(c(3,4),times=5e5),FUN=rpois,n=1)

but it requires rpois to be called far more times than needed.

My best attempt so far has been to transform it into a matrix and reconvert back into a vector:

d <- c(rbind(rpois(lambda=3,n=5e5),rpois(lambda=4,n=5e5)))
d <- c(rbind(a,b))

Is there a better way to go about doing it? Or is there a function in base R that accomplishes the same thing?

Blue Magister
  • 13,044
  • 5
  • 38
  • 56

2 Answers2

16

Your rbind method should work well. You could also use

rpois(lambda=c(3,4),n=1e6)

because R will automatically replicate the vector of lambda values to the required length. There's not much difference in speed:

library(rbenchmark)
benchmark(rpois(1e6,c(3,4)),
     c(rbind(rpois(5e5,3),rpois(5e5,4))))


#                                        test replications elapsed relative
# 2 c(rbind(rpois(5e+05, 3), rpois(5e+05, 4)))          100  23.390 1.112168
# 1                      rpois(1e+06, c(3, 4))          100  21.031 1.000000

and elegance is in the eye of the beholder ... of course, the c(rbind(...)) method works in general for constructing alternating vectors, while the other solution is specific to rpois or other functions that replicate their arguments in that way.

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
4

Some speed tests, incorporating Ben Bolker's answer:

 benchmark(
 c(rbind(rpois(lambda=3,n=5e5),rpois(lambda=4,n=5e5))),
 c(t(sapply(X=list(3,4),FUN=rpois,n=5e5))),
 sapply(X=rep.int(c(3,4),times=5e5),FUN=rpois,n=1),
 rpois(lambda=c(3,4),n=1e6),
 rpois(lambda=rep.int(c(3,4),times=5e5),n=1e6)
 )
                                                                  test
1 c(rbind(rpois(lambda = 3, n = 5e+05), rpois(lambda = 4, n = 5e+05)))
2                 c(t(sapply(X = list(3, 4), FUN = rpois, n = 5e+05)))
4                                   rpois(lambda = c(3, 4), n = 1e+06)
5           rpois(lambda = rep.int(c(3, 4), times = 5e+05), n = 1e+06)
3      sapply(X = rep.int(c(3, 4), times = 5e+05), FUN = rpois, n = 1)
  replications elapsed   relative user.self sys.self user.child sys.child
1          100    6.14   1.000000      5.93     0.15         NA        NA
2          100    7.11   1.157980      7.02     0.02         NA        NA
4          100   14.09   2.294788     13.61     0.05         NA        NA
5          100   14.24   2.319218     13.73     0.21         NA        NA
3          100  700.84 114.143322    683.51     0.50         NA        NA
NelsonGon
  • 13,015
  • 7
  • 27
  • 57
Blue Magister
  • 13,044
  • 5
  • 38
  • 56
  • 1
    I'm quite shocked to see just how well the `rbind` command works here. I seem to remember useRs very strongly protesting rbind and cbind as memory gobblers... – AdamO Dec 18 '17 at 17:14