data.table中的快速EXISTS

Jua*_*tro 5 r data.table

检查data.table中是否存在值的最快方法是什么?假设

  • dt是n列的data.table,其中k列是键
  • keys是一个列表,一个值,一个data.table,或者可以在i参数中使用的任何东西[.data.table

我现在正在做

NROW(dt[keys,nomatch=0])!=0
Run Code Online (Sandbox Code Playgroud)

有什么更快的吗?

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
Run Code Online (Sandbox Code Playgroud)

Aru*_*run 6

简短的回答:除此之外nomatch=0,我认为mult="first"这将有助于加快速度.

答案很长:假设你想要检查一个或哪个的关键列中是否存在一个值(或超过1个值)data.table,这似乎要快得多.这里唯一的假设是data.table只有一个键列(因为这对我来说很模糊).

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 
Run Code Online (Sandbox Code Playgroud)

如果要检查子集中是否存在至少1个值,则可以更改allany.两者之间的唯一区别是你首先subset使用data.table的方法(利用keymult参数).正如你所看到的那样它的速度非常快(并且也能很好地扩展).然后从子集中检索关键列(调用它the_subset),

.subset2(the_subset, "V1") (or) the_subset$V1 (or) the_subset[["V1"]]
Run Code Online (Sandbox Code Playgroud)

但是,the_subset[, V1]会慢一些.

当然,同样的想法也可以扩展到许多专栏,但我必须确切地知道你想要做什么.