r - How to find the min of the previous n values for every element of a vector? -


so far use loops within function this:

# x vector of numbers # [1] 0 1 -1 -5 100 20 15  function(x,n){    results <- numeric(length(x)-n+1)    for(i in 1:(length(x)+1-n)){     results[i] <- min(x[i:(i+n-1)])   }    return(results) }  ## outputs x , n = 3 # [1] -1 -5 -5 -5 15 

i wondering if there more efficient solution potentially not require looping.

edit::

i ran 2 of solutions microbenchmark on vector 6019 observations. when time (/figure out how), can try each solution various observation sizes see effectiveness of each solution. now:

rcpp solution:

> microbenchmark(nmin(x,3)) unit: microseconds        expr    min     lq     mean  median     uq    max neval  nmin(x, 3) 53.885 54.313 57.01953 54.7405 56.023 93.656   100 

catools solution:

microbenchmark(runmin(x[[1]],3,endrule='trim')) unit: microseconds                                 expr     min       lq     mean  median       uq     max neval  runmin(x[[1]], 3, endrule = "trim") 231.788 241.8385 262.6348 249.964 262.5795 833.923   100 

zoo solution:

> microbenchmark(rollapply(x[[1]],3,min)) unit: milliseconds                       expr     min      lq     mean   median       uq      max neval  rollapply(x[[1]], 3, min) 42.2123 47.2926 50.40772 50.33941 52.50033 98.46828   100 

my solution:

  > microbenchmark(ndaylow(x[[1]],3)) unit: milliseconds                  expr      min       lq     mean   median       uq      max neval  ndaylow(x[[1]], 3) 13.64597 14.51581 15.67343 15.33006 15.71324 63.68687   100 

sounds use-case rcpp. copy-paste , use other function. sure there many ways make more efficient (what mean not particularly @ c++ , i'm pretty sure can make use of nice stls here):

require(rcpp) rcpp::cppfunction( 'integervector nmin( numericvector x , int n ){   int n = x.size();   integervector out(n-n+1);     for( int = 0; < out.size(); ++i){         int nmin=x[i];         for( int j = 0; j < n; ++j){           int tmp=x[j+i];           if( tmp < nmin ){             nmin=tmp;           }         }         out[i]=nmin;     }   return out; }')  nmin(x,3) #[1] -1 -5 -5 -5 15 nmin(x,7) #[1] -5 

it's 30-fold quicker runmin:

print( microbenchmark(runmin(x,3,endrule='trim'),nmin(x,3),unit="relative") , digits = 1 ) #unit: relative #                           expr min lq median uq max neval # runmin(x, 3, endrule = "trim")  55 41     36 34  19   100 #                     nmin(x, 3)   1  1      1  1   1   100 

Comments

Popular posts from this blog

java - Oracle EBS .ClassNotFoundException: oracle.apps.fnd.formsClient.FormsLauncher.class ERROR -

c# - how to use buttonedit in devexpress gridcontrol -

nvd3.js - angularjs-nvd3-directives setting color in legend as well as in chart elements -