How to generate the following sequence without resorting to a cycle?

time<-c(10,20)
d<-NULL
for ( i in seq(length(time)))
d<-c(d,seq(0,(time[i]-1)))
d

When the time<-c(3000,4000,2000,...,5000)length of time is 1000, the procedure is very slow. Is there a faster way to generate a sequence without a loop?

Thank you for your help.

+5
source share
4 answers

Try d <- unlist(lapply(time,function(i)seq.int(0,i-1)))

On the side, one thing that slows it all down is that you grow a vector inside a loop.

> time<-sample(seq(1000,10000,by=1000),1000,replace=T)

> system.time({
+  d<-NULL
+  for ( i in seq(length(time)))
+  d<-c(d,seq(0,(time[i]-1)))
+  }
+ )
   user  system elapsed 
   9.80    0.00    9.82 

> system.time(d <- unlist(lapply(time,function(i)seq.int(0,i-1))))
   user  system elapsed 
   0.00    0.00    0.01 

> system.time(unlist(mapply(seq, 0, time-1)))
   user  system elapsed 
   0.11    0.00    0.11 

> system.time(sequence(time) - 1)
   user  system elapsed 
   0.15    0.00    0.16 

Edit: added time for other solutions as well

+8
source

It is much faster than a cycle, but not as fast as previous solutions mapplyand lapply; however, it is very simple:

sequence(time) - 1

and inside he uses lapply.

+6
source
time<-c(10, 20, 30)
unlist(mapply(seq, 0, time-1))

 [1]  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
[26] 15 16 17 18 19  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
[51] 20 21 22 23 24 25 26 27 28 29
+3

As @Joris hinted, the reason your solution is not working well was due to the growth of the vector. If you just guessed the size of the vector and allocated memory, respectively, your decision would have performed OK - still not optimal.

Using the @Joris example, your solution on my machine took 22 seconds. By preselecting a large vector, we can reduce this to about 0.25 s

> system.time({
+   d = numeric(6000000); k = 1 
+   for (i in seq(length(time))){
+     l = time[i]-1
+     d[k:(k+l)] = 0:l
+     k = k +l + 1
+   }}
+ )
  user  system elapsed 
 0.252   0.000   0.255 
+1
source