Tony
Tony

Reputation: 2929

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

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

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

Thanks for your help.

Upvotes: 5

Views: 1744

Answers (4)

csgillespie
csgillespie

Reputation: 60462

As @Joris hinted at, the reason why your solution perform poorly, was because of vector growth. If you just guessed at the size of the vector and allocated memory accordingly, your solution would have perform OK - still not optimal though.

Using the example of @Joris, your solution on my machine took 22secs. By pre-allocating a large vector, we can reduce that to around 0.25secs

> 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 

Upvotes: 1

Joris Meys
Joris Meys

Reputation: 108533

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

On a sidenote, one thing that slows down the whole thing, is the fact that you grow the vector within the 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 timing for other solutions as well

Upvotes: 8

G. Grothendieck
G. Grothendieck

Reputation: 269526

This is much faster than the loop but not quite as fast as the mapply and lapply solutions shown previously; however, it is very simple:

sequence(time) - 1

and internally it uses a lapply .

Upvotes: 6

Andrie
Andrie

Reputation: 179418

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

Upvotes: 3

Related Questions