The latest version of data.table has added the %between% and %inrange% that encapsulate this behavior. It seems like this solution based on the Psidom movie is a bit slower, but handles all types (numeric / integer) as expected, and much more concise. See below.
# data.table version 1.10.4 # R version 3.3.1 (2016-06-21) set.seed(123L) library(data.table) x = runif(1E6) DT = data.table(x) #Psidom Answer psidom <- function() DT[{ind <- DT[.(c(0.04, 0.5)), which=TRUE, roll=TRUE, on=.(x)]; (ind[1]+1):ind[2]}] # Unkeyed microbenchmark::microbenchmark( DT[x <= 0.5 & x >= 0.04], x[x <= 0.5 & x >= 0.04], DT[x %between% c(0.04, 0.5)], DT[x %inrange% c(0.04, 0.5)], DT[.(0.04, 0.5), on = .(x >= V1, x <= V2), .(xx)] ) # Unit: milliseconds # expr min lq mean median uq max neval cld # DT[x <= 0.5 & x >= 0.04] 20.346712 23.983928 34.69493 25.21085 26.73657 281.4747 100 b # x[x <= 0.5 & x >= 0.04] 19.581049 22.935144 31.61551 23.83557 25.99587 145.3632 100 b # DT[x %between% c(0.04, 0.5)] 8.024091 9.293261 12.19035 11.38171 12.75843 116.5132 100 a # DT[x %inrange% c(0.04, 0.5)] 77.108485 79.871207 91.05544 81.83722 84.66684 188.8674 100 c # DT[.(0.04, 0.5), on = .(x >= V1, x <= V2), .(xx)] 189.488658 195.487681 217.55708 198.52696 205.80428 318.1696 100 d # Keyed setkey(DT,x) #Psidom Answer psidom <- function() DT[{ind <- DT[.(c(0.04, 0.5)), which=TRUE, roll=TRUE, on=.(x)]; (ind[1]+1):ind[2]}] microbenchmark::microbenchmark( DT[x <= 0.5 & x >= 0.04], x[x <= 0.5 & x >= 0.04], DT[x %between% c(0.04, 0.5)], DT[x %inrange% c(0.04, 0.5)], DT[.(0.04, 0.5), on = .(x >= V1, x <= V2), .(xx)], psidom() ) # Unit: milliseconds # expr min lq mean median uq max neval cld # DT[x <= 0.5 & x >= 0.04] 14.550788 18.092458 21.012992 18.934781 20.055428 123.1174 100 b # x[x <= 0.5 & x >= 0.04] 19.403718 22.401709 27.296872 23.707688 24.608270 128.9123 100 b # DT[x %between% c(0.04, 0.5)] 5.439340 6.819262 10.789330 9.490118 10.561789 111.6523 100 a # DT[x %inrange% c(0.04, 0.5)] 12.871260 13.894918 21.434823 16.888748 18.128147 123.4275 100 b # DT[.(0.04, 0.5), on = .(x >= V1, x <= V2), .(xx)] 49.277678 53.516350 61.422212 54.499675 55.869354 158.1861 100 c # psidom() 4.615421 5.095880 9.482131 5.325707 8.316817 109.9318 100 a