2013-02-27 2 views
4

У меня есть data.table структуру, как это (кроме меня это действительно огромный):Keyed поиск по data.table без «с»

dt <- data.table(x=1:5, y=3:7, key='x') 

Я хочу посмотреть строки в этой структуре по другой переменной, имя x (заметьте - такой же, как имя ключа dt):

x <- 3:4 
dt2 <- dt[ J(x) ] 

Это не работает, потому что поиск видит имя столбца первой, а локальная переменная затемняется:

dt2 
# x y 
# 1: 1 3 
# 2: 2 4 
# 3: 3 5 
# 4: 4 6 
# 5: 5 7 

Я думал о with аргумент для [.data.table, но это относится только к j аргумента, а не i аргумента.

Есть ли что-то подобное для аргумента i?

Если нет, такая вещь будет полезна всякий раз, когда я использую локальную переменную, и я не знаю полного списка имен столбцов в dt, чтобы избежать конфликтов.

+0

В НОВОСТИ for 1.8.2 есть пункт, который предполагает, что синтаксис '..()' запланирован для оценки в вызывающем кадре. Он, кажется, не находится в '1.8.7' – mnel

ответ

8

Существует элемент в НОВОСТЯХ для 1.8.2, который предлагает синтаксис ..() будет добавлен в каком-то момент, что позволяет этого

Нового DT синтаксис [. (...)] (в стиле пакета plyr) идентичен DT [список (...)], DT [J (...)] и DT [data.table (...)]. Мы планируем добавить ..() тоже, так что что.() И ..() аналогичны файловой системе ./ и ../; то есть.() оценивает в рамках DT и ..() в родительской области.

В то же время, вы можете get из соответствующей среды

dt[J(get('x', envir = parent.frame(3)))] 
## x y 
## 1: 3 5 
## 2: 4 6 

или вы могли бы eval весь вызов list(x) или J(x)

dt[eval(list(x))] 
dt[eval(J(x))] 
dt[eval(.(x))] 
+0

Вы должны использовать другой' dt' или другой 'x'. –

+0

А, да, мой «x <- 2: 3» (я мог бы поклясться, что я скопировал вопрос, хотя он был в 5-минутном льготном периоде) – mnel

+0

@Dwin, исправлено с правильной 'x' – mnel

2

Новый ответ, теперь, когда я думаю, Я понимаю, что было запрошено:

> X <- data.table(x=x) 
> merge(dt, X) 
    x y 
1: 3 6 
2: 4 7 
+0

вы можете сохранить два нажатия клавиши 'data.table (x)' – mnel

+0

Хороший краткий ответ. –

+1

Я только что понял (из бенчмаркинга) это не использует индекс на 'dt', поэтому, к сожалению, это не сработает. Я думал, что я где-то читал, что «слияние» должно было использовать индекс, если возможно, хотя? –

0

Добавление некоторых результатов бенчмаркинга по запросу.

dt - объект 53080731 x 5 data.table, снабженный цифровым столбцом со 100 уникальными значениями, довольно равномерно распределенными. x - это вектор, содержащий 5 таких значений.

library(microbenchmark) 
> mb <- microbenchmark(
+  dt[eval(J(x))], 
+  merge(dt, data.table(x)), 
+  times=10 
+) 
> mb 
Unit: milliseconds 
        expr  min  lq median  uq  max neval 
      dt[eval(J(x))] 127.324 127.549 133.5305 154.410 159.433 10 
merge(dt, data.table(x)) 5028.349 5083.792 5129.6590 5170.451 5250.255 10 

@Tyler, если вы можете помочь мне с тем, как использовать qdap::lookup() для этого случая с несколькими столбцами, я могу добавить, что тоже.

Смежные вопросы