2013-06-26 3 views
5

Каков самый быстрый способ проверить, существует ли значение в data.table ?. ПустьБыстрые EXISTS в data.table

  • дт является data.table п столбцов с к столбцам являются ключевыми
  • ключей список, или значение, или 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

Всегда лучше показать пример того, что вы пытаетесь сделать. Вы говорите «значение». И вы проверяете только одно значение? Также вы проверяете только один столбец data.table 'dt'? Является ли «ключ» 1-столбцом data.table? Поэтому я нахожу этот вопрос неопределенным. – Arun

+0

@Arun Извините за неопределенность, надеюсь, что последнее редактирование помогает. Я ищу общее решение, а не только для случая, когда аргумент i является значением, или ключ - это всего лишь один столбец – Juancentro

+1

, вам придется объяснить, отредактировав свой вопрос немного более подробно. – Arun

ответ

6

Короткий ответ: В дополнение к nomatch=0, думаю, mult="first" поможет ускорить его еще больше.

Длинный ответ: Если предположить, что вы хотите проверить, если значение (или более чем 1 значение) присутствует в ключа столбца data.table или нет, но это, кажется, гораздо быстрее. Единственное предположение здесь состоит в том, что data.table имеет только 1 ключевой столбец (так как это довольно неоднозначно для меня).

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 

Вы можете изменить all к any, если вы хотите, чтобы проверить, по крайней мере, 1 значение присутствует в подгруппе или нет. Единственное различие между ними состоит в том, что вы сначала subset, используя подход data.table (воспользовавшись аргументом key и mult). Как вы можете видеть, это очень быстро (и также хорошо масштабируется). А затем, чтобы получить ключевые столбцы из подмножества (назовем его the_subset),

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

Но the_subset[, V1] будет медленнее.

Конечно, та же идея может быть распространена и на многие столбцы, но я должен буду точно знать, что вы хотите делать.

+0

Спасибо Аруну, просто получить первый результат, несомненно, ускорит вычисления. – Juancentro

+0

Я изо всех сил пытаюсь расширить этот ответ на несколько ключевых столбцов прямо сейчас. –

3

Как насчет базы R идиомы:

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

Это не data.table конкретных идиома, но и является достаточно эффективным я считаю.

+1

'any (my.value == my.vector)' быстрее в моем тестировании, хотя и на 0,3 с быстрее, когда 'my.vector' составляет 10M значений. – thelatemail

+0

Bummer! Извините, что я имею лишь незначительную помощь. : D – asb

+0

@thelatemail предположительно 'my.value' имеет длину больше 1, так как она называется' keys' в OP. – GSee