开发者

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

开发者 https://www.devze.com 2023-02-19 13:43 出处:网络
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 len开发者_如何转开发gth of time is 1000, the procedure is
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 len开发者_如何转开发gth of time is 1000, the procedure is very slow. Is there a faster way generating the sequence without looping?

Thanks for your help.


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


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 .


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


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 
0

精彩评论

暂无评论...
验证码 换一张
取 消