Could someone give me an idea on how to do rolling ranking, i.e. rank in the moving window of last 100 numbers in a long vector? I tried naive solution like roll.rank<-function(v, len){ r<-numeric(length(v)-len+1) for(i in len:length(v)) r[i-len+1]<-rank(v[(i-len+1):i])[len] r } However, it turns out pretty slow even on my rather able Linux box. For example, doing roll.rank(rnorm(50000), 100) takes 5 second, so for typical data i operate which is matrices of the size 1000 x 50000 i will need to wait 1.5 hours for one calculation. Does someone know a trick to properly do it quicker? -- View this message in context: http://n4.nabble.com/efficient-rolling-rank-tp2013535p2013535.html Sent from the R help mailing list archive at Nabble.com.
I don't know if its any faster but you could try: library(zoo) z <- zoo(v) rollapply(z, len, function(x) rank(x)[len]) On Fri, Apr 16, 2010 at 4:21 PM, zerdna <azege at yahoo.com> wrote:> > Could someone give me an idea on how to do rolling ranking, i.e. rank in the > moving window of last 100 numbers in a long vector? I tried naive solution > like > > roll.rank<-function(v, len){ > ? ?r<-numeric(length(v)-len+1) > ? ?for(i in len:length(v)) > ? ? ? ?r[i-len+1]<-rank(v[(i-len+1):i])[len] > ? ?r > > } > > However, it turns out pretty slow even on my rather able Linux box. For > example, doing roll.rank(rnorm(50000), 100) takes 5 second, so for typical > data i operate which is matrices of the size 1000 x 50000 i will need to > wait 1.5 hours for one calculation. Does someone know a trick to properly do > it quicker? > -- > View this message in context: http://n4.nabble.com/efficient-rolling-rank-tp2013535p2013535.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
On Fri, 16 Apr 2010, zerdna wrote:> > Could someone give me an idea on how to do rolling ranking, i.e. rank in the > moving window of last 100 numbers in a long vector? I tried naive solution > like > > roll.rank<-function(v, len){ > r<-numeric(length(v)-len+1) > for(i in len:length(v)) > r[i-len+1]<-rank(v[(i-len+1):i])[len] > r > > } > > However, it turns out pretty slow even on my rather able Linux box. For > example, doing roll.rank(rnorm(50000), 100) takes 5 second, so for typical > data i operate which is matrices of the size 1000 x 50000 i will need to > wait 1.5 hours for one calculation. Does someone know a trick to properly do > it quicker?Vectorize it with embed:> x <- rnorm(50000) > system.time(x.rank <- rowSums(x[ -(1:99) ] >= embed(x,100) ))user system elapsed 0.295 0.131 0.424> system.time(x.rank.2 <- roll.rank(x,100))user system elapsed 6.907 0.033 6.940> all.equal(x.rank,x.rank.2)[1] TRUE>N.B., if there are ties, you may want to adjust when rowSums(x[ -(1:99) ] == embed(x,100) ) is greater than 1. If you want much faster, package inline would enable you to write something equivalent in C. HTH, Chuck> -- > View this message in context: http://n4.nabble.com/efficient-rolling-rank-tp2013535p2013535.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >Charles C. Berry (858) 534-2098 Dept of Family/Preventive Medicine E mailto:cberry at tajo.ucsd.edu UC San Diego http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego 92093-0901