Как выполнить операцию слияния data.table
-
19-09-2019 - |
Вопрос
примечание:этот вопрос и следующие ответы относятся к версиям data.table < 1.5.3;в.Версия 1.5.3 была выпущена в феврале 2011 года для решения этой проблемы. см. более недавнее обращение (03-2012): Перевод SQL-соединений по внешним ключам в синтаксис R data.table
Я копался в документации по пакет data.table (замена data.frame, которая гораздо более эффективна для определенных операций), в том числе Презентация Джоша Райха по SQL и data.table на 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
Документы говорят, что «когда [первый аргумент] сам по себе является данным. Ясно, что это не так.Могу ли я получить другие столбцы из y в результат x[y] с помощью data.tables?Кажется, что он просто берет строки x, где ключ соответствует ключу y, но полностью игнорирует остальную часть y...
Решение
Вы цитируете не ту часть документации.Если вы посмотрите документ [.data.table
вы прочтете:
Когда я являюсь данными. вернуть ряды в x, которые соответствуют.Equi-Join выполняется между каждым столбцом в I к каждому столбцу в ключе X в порядке.Это похоже на функциональность базовой r для установления матрицы на матрицу с двумя колонками, а в более высоких измерениях подгруппируют N-размерный массив по матрице N-Column
Я признаю, что описание пакета (та часть, которую вы процитировали) несколько сбивает с толку, поскольку там, кажется, говорится, что вместо слияния можно использовать операцию «[».Но я думаю, что там написано следующее:если x и y оба являются data.tables, мы используем соединение по индексу (которое вызывается как слияние) вместо двоичного поиска.
Еще кое-что:
Библиотека data.table, которую я установил через install.packages
не хватало merge.data.table method
, поэтому используя merge
назвал бы merge.data.frame
.После установки пакет от R-Forge R использовал более быстрый merge.data.table
метод.
Вы можете проверить, есть ли у вас метод merge.data.table, проверив вывод:
methods(generic.function="merge")
РЕДАКТИРОВАТЬ [Ответ больше не действителен]: Этот ответ относится к data.table версии 1.3.В версии 1.5.3 поведение data.table изменилось, и x[y] возвращает ожидаемые результаты.Спасибо Мэтью Доул, автору data.table, за указание на это в комментариях.
Другие советы
Спасибо за ответы.Я пропустил эту тему, когда она была изначально опубликована.data.table переехал с февраля.Версия 1.4.1 была выпущена в CRAN некоторое время назад, а скоро выйдет версия 1.5.Например, псевдоним DT() был заменен на list();в качестве примитива это происходит намного быстрее, а data.table теперь наследуется от data.frame, поэтому он работает с пакетами, которые только принять data.frame, такой как ggplot и решетку, без необходимости преобразования (быстрее и удобнее).
Можно ли подписаться на тег data.table, чтобы получать электронное письмо, когда кто-то публикует вопрос с этим тегом?Список помощи по datatable вырос примерно до 30-40 сообщений в месяц, но я буду рад ответить и здесь, если получу какое-то уведомление.
Мэтью
Я думаю, используя 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
Что не могло составить большой беды :)
Я думаю, что f3lix прав, а документация немного вводит в заблуждение.Преимущество заключается в быстром соединении для подмножества данных.В конечном итоге вам все равно придется использовать merge
функционируйте впоследствии, как в приведенном выше примере.
Вы увидите в Презентация Джоша об использовании data.table что именно так работает его пример.Сначала он подмножество одной из таблиц data.tables, затем выполняет слияние:
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')]