Home > front end >  Examine if a value is in an interval using R
Examine if a value is in an interval using R

Time:09-24

Having the following vector:

t <- c(2, 6, 8, 20, 22, 30, 40, 45, 60)

I would like to find the values that fall between the following intervals:

g <- list(c(1,20), c(20, 40))

The desired output is:

1, 20 c(2, 6, 8)
20, 40 c(20, 22, 30)

Using the dplyr library, I do the following:

library(dplyr)
for(i in t){
    for(h in g){
        if(between(i, h[[1]], h[[2]])==TRUE){print(c(i, h[[1]], h[[2]]))}
}}

Is there a better way of doing this in R?

CodePudding user response:

We can loop over the list 'g' and extract the 't' elements based on the first and second values by creating a logical vector with >/< and extract the elements of 't'

lapply(g, function(x) t[t >= x[1] & t  < x[2]])

-output

[[1]]
[1] 2 6 8

[[2]]
[1] 20 22 30

CodePudding user response:

library(purrr)
library(dplyr)

map(g,~keep(t,between(t,.[1],.[2])))

[[1]]
[1]  2  6  8 20

[[2]]
[1] 20 22 30 40

CodePudding user response:

You may find findInterval() from base R useful:

g <- c(1, 20, 40)
t <- c(2, 6, 8, 20, 22, 30, 40, 45, 60)
findInterval(t, g)
#> [1] 1 1 1 2 2 2 3 3 3

So t[1], t[2] and t[3] are in the first interval, t[4], t[5] and t[6] in the second, and t[7], t[8] and t[9] the third (meaning that these values are bigger than the right end point of the second interval.) If you had values lower than one they would be labelled by 0:

t2 <- c(-1, 0, 2, 6, 8, 20, 22, 30, 40, 45, 60)
findInterval(t2, g)
#>  [1] 0 0 1 1 1 2 2 2 3 3 3

You can save the result of findInterval() as e.g. y and use which(y==1) to find which entries correspond to the first interval.

CodePudding user response:

We can try cut is.na like below

lapply(
  g,
  function(x) {
    t[!is.na(cut(t, x, include.lowest = TRUE))]
  }
)

which gives

[[1]]
[1]  2  6  8 20

[[2]]
[1] 20 22 30 40
  • Related