2010-02-09 22 views
43

примечание: этот вопрос и последующие ответы относятся к data.table версии < 1.5.3; v. 1.5.3 был выпущен в феврале 2011 года для решения этой проблемы. увидеть более недавнее лечение (03-2012): Translating SQL joins on foreign keys to R data.table syntaxКак выполнить операцию слияния данных.table


Я копаться в документации для data.table package (замены data.frame, что гораздо более эффективным для некоторых операций), в том числе Josh Reich's presentation on SQL and data.table at the NYC R Meetup (PDF), но не может понять эту полностью тривиальную операцию.

> x <- DT(a=1:3, b=2:4, key='a') 
> x 
    a b 
[1,] 1 2 
[2,] 2 3 
[3,] 3 4 
> y <- DT(a=1:3, c=c('a','b','c'), key='a') 
> y 
    a c 
[1,] 1 a 
[2,] 2 b 
[3,] 3 c 
> x[y] 
    a b 
[1,] 1 2 
[2,] 2 3 
[3,] 3 4 
> merge(x,y) 
    a b c 
1 1 2 a 
2 2 3 b 
3 3 4 c 

документы говорят, «Когда [первый аргумент] сам по себе является data.table, объединение вызываются аналогично базировать :: слияние, но использует бинарный поиск по отсортированному ключу.» Ясно, что это не так. Могу ли я получить другие столбцы от y в результате x [y] с data.tables? Кажется, что он просто берет строки x, где ключ совпадает с ключом y, но игнорирует остальную часть y целиком ...

+2

Это было разрешено v1.5.3 выпущено в CRAN в феврале 2011 года. См. Его НОВОСТИ, новые данные.table и исправленные FAQ. –

ответ

27

Вы цитируете неправильную часть документации. Если вы посмотрите на документ из [.data.table вы будете читать:

Когда я это data.table, х должен иметь ключ, то есть присоединиться к I х и возвращения строки в х, которые соответствуют. Equi-join выполняется между каждым столбцом в i для каждого столбца по клавише x по порядку. Это похоже на базу R функциональности подмножества матрицы матрицей 2-столбца, а в более высоких размерах подмножества п-мерный массив с помощью матрицы н-колонки

Я признаю описание пакета (часть, которую вы цитировали) несколько сбивает с толку, потому что кажется, что «[-операция может использоваться вместо слияния). Но я думаю, что он говорит: если x и y - оба data.tables, мы используем объединение по индексу (которое вызывается как merge) вместо бинарного поиска. более


одно:

data.table библиотека Я установил через install.packages пропускал merge.data.table method, поэтому использование merge назвали бы merge.data.frame. После установки package from R-Forge R используется более быстрый метод merge.data.table.

Вы можете проверить, если у вас есть merge.data.table метод, проверив вывод:

methods(generic.function="merge") 

EDIT [Ответ больше не действителен]: Этот ответ относится к data.table версия 1.3. В версии 1.5.3 поведение data.table изменено, а x [y] возвращает ожидаемые результаты. Спасибо Matthew Dowle, автор data.table, за указание на это в комментариях.

+0

Ах. Похоже, что версия на CRAN - версия 1.2, а версия на R-Forge - версия 1.3. Метод 'merge', по-видимому, был добавлен в 1.3. Из того, что я могу сказать, глядя вокруг R-Forge, этот метод был добавлен примерно как 8 месяцев назад, поэтому я не знаю, почему это еще не на CRAN! – Harlan

+5

Синтаксис X [Y] был изменен в v1.5.3, выпущенном в CRAN в феврале 2011 года. См. Его НОВОСТИ, новые данные. Таблица и исправленные FAQ. –

3

Я думаю, что f3lix верен и что документация немного вводит в заблуждение. Преимуществом является быстрое соединение для подмножества данных.В конечном итоге вам необходимо использовать функцию merge, как показано в приведенном выше примере.

Вы увидите в Josh's presentation on using data.table, что так работает его пример. Сначала он подмножает один из данных. Затем слияние:

library(data.table) 
sdt <- DT(series, key='series_id') 
ddt <- DT(data, key='series_id') 
u <- sdt[ grepl('^[A-Z]{2}URN', fred_id) & !grepl('DSURN', fred_id) ] 
d <- ddt[ u, DT(min=min(value)), by='series_id', mult='all'] 
data <- merge(d,series)[,c('title','min','mean','max')] 
+0

Спасибо, Шейн. Я был очень смущен этим, так как знал (или думал, что знаю), что «слияние» не будет использовать преимущества «data.table». – Harlan

14

Спасибо за ответы. Я пропустил эту тему, когда она была изначально отправлена. data.table переместилась с февраля. 1.4.1 был выпущен в CRAN некоторое время назад, а 1.5 - в ближайшее время. Например, псевдоним DT() был заменен на list(); как примитивнее его намного быстрее, а data.table теперь наследуется от data.frame, поэтому он работает с пакетами, которые только принимают data.frame, такие как ggplot и решетка, без какого-либо преобразования (быстрее и удобнее).

Можно ли подписаться на тег data.table, чтобы получить электронное письмо, когда кто-то отправляет вопрос с этим тегом? Список datatable-help вырос до 30-40 сообщений в месяц, но я тоже с удовольствием отвечу здесь, если я получу какое-то уведомление.

Мэтью

+1

Привет, спасибо за примечание! Да, это определенно возможно. Нажмите на поле «data.table'» в правом верхнем углу экрана, затем прокрутите вниз до тех пор, пока не увидите значок RSS, и не используйте это, чтобы подписаться на вопросы с этим тегом. – Harlan

+0

Спасибо Харлан. Я подписался сейчас. –

9

Я думаю, что с помощью функции base::merge не нужен, так как с помощью data.table присоединяется может быть намного быстрее. Например. см. следующее. Я делаю x и y data.tables с 3-3 колонки:

> x <- data.table(foo = 1:5, a=20:24, zoo = 5:1) 
> y <- data.table(foo = 1:5, b=30:34, boo = 10:14) 
> setkey(x, foo) 
> setkey(y, foo) 

И объединить оба с base:merge и data.table присоединяется, чтобы увидеть скорость выполнений:

> system.time(merge(x,y)) 
    user system elapsed 
    0.027 0.000 0.023 
> system.time(x[,list(y,x)]) 
    user system elapsed 
    0.003 0.000 0.006 

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

> merge(x,y) 
    foo a zoo b boo 
[1,] 1 20 5 30 10 
[2,] 2 21 4 31 11 
[3,] 3 22 3 32 12 
[4,] 4 23 2 33 13 
[5,] 5 24 1 34 14 
> x[,list(x,y)] 
    foo a zoo foo.1 b boo 
[1,] 1 20 5  1 30 10 
[2,] 2 21 4  2 31 11 
[3,] 3 22 3  3 32 12 
[4,] 4 23 2  4 33 13 
[5,] 5 24 1  5 34 14 

Что не может сделать большие неприятности :)

+3

Спасибо, это интересно. Тем не менее, совершенно неочевидный синтаксис! Если бы я использовал это, я мог бы переопределить функцию, которая выполняет 'function (x, y) x [, list (x, y)]' или что-то еще, возможно, сбросив лишний ключевой столбец ... – Harlan

+2

Я думаю, что это правильно синтаксис для объединений в data.table - фактически x [y] или x [y,], то есть соединения должны использовать первый индекс. Это дает те же результаты, что и слияние. обратите внимание, что x [y] и y [x] не обязательно должны быть одинаковыми, т. е. если y содержит записи в foo, которые не являются репрезентативными для x. Возможно, я пропустил что-то, но вижу Joins в data.table [виньетка] (http://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.pdf) – cboettig

+1

выше x [, list (x, y)] не работает для меня. Я попробовал x [, c (x, y)], и он сработал. Я не уверен, что это имеет смысл. – bala

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