Finding values below a threshold I am wondering if it's possible to avoid looping. I want to make the function faster. The function is to find how many times a particular value is lower in the overall data. For example:

Value &lt;- c(0,10,5,1,0,0,11,0,0,7,3,2,5) # length =13


The 1st value is 0 and 0 is NOT lower in any of the values. Therefore the value I would like to return from the function would be 0.

Something like this:

sum(Values &lt; 0) 
0


The 2nd value is 10:

sum(Values &lt; 10)
11


I make a function something like below:

fun_num &lt;- function(Value){
  gg &lt;- vector()
  for (i in seq_along(Value)){
    x &lt;- Value[i]
    y &lt;- sum(Value &lt; x)
    gg[i] &lt;- y
  }
  return(gg)
}


Applying the function:

fun_num(Value)

[1]  0 11  8  5  0  0 12  0  0 10  7  6  8


Just wondering, is there a way to speed this function up using sapply and avoid using for loop?
This should suffice    

fun_2 &lt;- function(x) sapply(x, function(y) sum(x &lt; y))
fun_2(Value)
# [1]  0 11  8  5  0  0 12  0  0 10  7  6  8


P.S. sapply/lapply are the same loops, just masked and a little bit faster.

Or if your data is very large we can do it a lot faster using data.table, aggregating the data and counting:

require(data.table)
fun_3 &lt;- function(Value) {
  d &lt;- data.table(x = Value) # creates 1 column data.table
  # setkey(d, x) # not needed here keyby sets the key
  d &lt;- d[, .N, keyby = x] # calculate count of each unique x value
  # and sorts the results
  d[, a := c(0, cumsum(N)[-.N])] # calculate lagged cumsum from N (counts)
  # a represents element count that is smaller than x
  d[.(Value), a] # using datatable-keys-fast-subset get a(result) for each Value
}

set.seed(42)
Value2 &lt;- sample.int(1e5)

system.time(r2 &lt;- fun_2(Value2)) # 36.64 
system.time(r3 &lt;- fun_3(Value2)) # 0.03 
all.equal(r2, r3)
# [1] TRUE


OR with base R:

fun_4 &lt;- function(x) {
  xorder &lt;- order(x)
  xsorted &lt;- x[xorder]
  xsdifs &lt;- c(0, diff(xsorted))
  m &lt;- seq_along(xsdifs) - 1L
  m[xsdifs == 0L] &lt;- 0L
  m &lt;- cummax(m)
  m[order(xorder)]
}


For reverse (Value &gt; x):

fun_2r &lt;- function(x) sapply(x, function(y) sum(x &gt; y))
fun_3r &lt;- function(Value) {
  d &lt;- data.table(x = Value)
  d &lt;- d[, .N, keyby = x]
  setorder(d, -x)
  d[, a := c(0, cumsum(N)[-.N])]
  setkey(d, x) # need to reset key for sub setting,
  # because reordering d removes it
  d[.(Value), a]
}