Is there a function that checks if a certain value is contained in a certain range?

Asked

Viewed 465 times

3

Supposing:

x=120,00
limites.inferior<-80
limites.superior<-160
limites<-c(limites.inferior,limites.superior)

I am performing this procedure with a logical test:

x.int<-x>=limites[1] && x<=limites[2]

There is a function that performs this simple check?

2 answers

4


You can get the same result by making a comparison less. As explained in response from the OS.

the Trick is to substract the Middle between low and high from x, and then check whether that Difference is Less than half of the Distance between low and high.

Translated into something like: The trick is to subtract half the sum of the lower limit and the upper limit of the number, and then check that the difference is less than half the distance between the lower limit and the upper limit.

In code you can have the following function:

in.interval2 <- function(numero, li, ls){
  abs(numero-(ls+li)/2) < (ls-li)/2 
}

> in.interval2(120, 80, 160)
[1] TRUE

In a matter of time, comparing to its function:

in.interval <- function(numero, li, ls){
  numero > li & numero < ls
}

> microbenchmark::microbenchmark(
+   in.interval(120, 80, 160),
+   in.interval2(120, 80, 160)
+ )
Unit: nanoseconds
                       expr  min   lq    mean median   uq   max neval cld
  in.interval(120, 80, 160)  708  709 1405.89   1062 1063 25836   100   a
 in.interval2(120, 80, 160) 1062 1416 2517.19   1417 1770 60872   100   a

And for slightly larger vectors.

> microbenchmark::microbenchmark(
+   in.interval(1:200, 80, 160),
+   in.interval2(1:200, 80, 160)
+ )
Unit: microseconds
                         expr   min    lq    mean median     uq    max neval cld
  in.interval(1:200, 80, 160) 6.725 7.079 8.20441  7.433 7.6095 33.268   100   b
 in.interval2(1:200, 80, 160) 3.186 3.540 4.49548  3.540 3.8940 20.528   100  a 

Note that this way vc is 30% faster to compare a number and 100% faster p/ compare 200 numbers.

In terms of time, I don’t think this will greatly accelerate your code, since the unit is microseconds (10 -6s) to the vector of 200. That is, you have to run this line at least 300,000 times for that change to accelerate at least 1s.

2

The closest I found was the function findInterval.

You can try something like:

x.int <- (findInterval(x, limites, rightmost.closed = TRUE) == 1)

But I honestly see no reason for you to stop using the test you’re currently using.

  • This condition is inside a loop, I want to make sure this process gets faster. I will leave the question open for some more time to see if other suggestions. Thank you very much!

  • This OS response can help. It benchmarks in many ways. The way Marcos put it, in large vectors, can increase performance by 2x. For small vectors, it doesn’t make much difference. In the answer, other forms are presented that increase up to 2x the performance p/ small vectors

Browser other questions tagged

You are not signed in. Login or sign up in order to post.