What is the fastest way to check if a value exists in a data.table?. Suppose that
i
argument of [.data.table
I'm currently doing
NROW(dt[keys,nomatch=0])!=0
Is there anything faster?
Example
require(data.table)
iniDate = as.Date("2000-01-01")
theData = data.table(a = LETTERS, d = seq(from=iniDate ,to= iniDate + length(LETTERS)*3000-1,by="day"))
theKeys = data.table(a = c("J","M","T"), d = as.Date(c("2005-01-20","2005-05-20","2013-01-12")))
setkey(theData,a,d)
NROW(theData[theKeys],nomatch=0)!=0
Short answer: In addition to nomatch=0
, I think mult="first"
would help speed it even more.
Long answer: Assuming that you want to check if a value (or more than 1 value) is present in the key column of a data.table
or not, this seems to be much faster. The only assumption here is that the data.table has only 1 key column (as this is quite ambiguous to me).
my.values = c(1:100, 1000)
require(data.table)
set.seed(45)
DT <- as.data.table(matrix(sample(2e4, 1e6*100, replace=TRUE), ncol=100))
setkey(DT, "V1")
# the data.table way
system.time(all(my.values %in% .subset2(DT[J(my.values), mult="first", nomatch=0], "V1")))
user system elapsed
0.006 0.000 0.006
# vector (scan) approach
system.time(all(my.values %in% .subset2(DT, "V1")))
user system elapsed
0.037 0.000 0.038
You can change all
to any
if you want to check if at least 1 value is present in the subset or not. The only difference between the two is that you first subset
using data.table
's approach (taking advantage of key
and mult
argument). As you can see the it's extremely faster (and also scales well). And then to retrieve the key columns from the subset (call it the_subset
),
.subset2(the_subset, "V1") (or) the_subset$V1 (or) the_subset[["V1"]]
But, the_subset[, V1]
will be slower.
Of course the same idea could be extended to many columns as well, but I'll have to know exactly what you want to do after.
How about the base R idiom:
any(my.value %in% my.vector)
This is not a data.table
specific idiom but is quite efficient I believe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With