data.table中的快速EXISTS

时间:2013-06-26 22:41:43

标签: r data.table

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

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

我正在做

NROW(dt[keys,nomatch=0])!=0

有什么更快的吗?

实施例

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

2 个答案:

答案 0 :(得分:6)

简短回答:除了nomatch=0之外,我认为mult="first"会有助于加快速度。

答案很长:假设您要检查data.table列中是否存在值(或超过1个值),这似乎很多快点。这里唯一的假设是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 

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

.subset2(the_subset, "V1") (or) the_subset$V1 (or) the_subset[["V1"]]

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

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

答案 1 :(得分:3)

基础R习语怎么样:

any(my.value %in% my.vector)

这不是data.table特定的习惯用法,但我相信它非常有效。