Search code examples
rranking

Cumulative-ranked n'th item in R


I have a list of items e.g.:

x=c(1.1, 1.3, 1.2, 1.4, 1.0)

and would like to produce the rolling n'th, eg using a function of the form cumrank(x,2) to mean the 3rd item (count starts at 0) rolling down the list to give something like:

cumrank(x,2)
-> NA, NA, 1.3, 1.3, 1.2

As we work down the list this requires sorting the the items to date, then finding the third item.

The built in cummin() and cummax() functions presumably order the list to date in increasing or decreasing order and then select the first item, but I wonder: is there a generalisation of those functions that would allow me to grab the n'th item, as required?


Solution

  • You can write your own function

    cumrank <- function(x, k){
      n <- length(x)
      y <- rep(NA, n)
      for (i in (k+1):n){
        y[i] = sort(x[1:i])[k + 1]        
      }
      y
    }
     cumrank(x, 2)
    [1]  NA  NA 1.3 1.3 1.2
    

    For lengthy vectors, Rcpp resolves the speed issue.

    library(Rcpp)
    cppFunction('std::vector<double> cumrank_Cpp(std::vector<double> x, int k) {
        int n = x.size();
        std::vector<double> v(x.begin(), x.begin() + k+1);
        std::make_heap(v.begin(), v.end());
        std::vector<double> nth(n);
        for(int i=k; i < n; i++){
          nth[i]=v.front();
          v.push_back(x[i+1]); std::push_heap(v.begin(), v.end()); 
          std::pop_heap(v.begin(), v.end()); v.pop_back();
        }
        return nth;
    }')