обзор
Я относительно знаком с data.table
, не так много с dplyr
. Я прочитал несколько dplyr
виньеток и примеров, которые всплыли на SO, и до сих пор мои выводы таковы:
data.table
иdplyr
сопоставимы по скорости, за исключением случаев, когда существует много (то есть> 10-100 КБ) групп, и при некоторых других обстоятельствах (см. контрольные показатели ниже)dplyr
имеет более доступный синтаксисdplyr
тезисы (или воля) потенциальных взаимодействий БД- Есть некоторые незначительные функциональные различия (см. «Примеры / Использование» ниже)
На мой взгляд, 2. не имеет большого веса, потому что я довольно знаком с ним data.table
, хотя я понимаю, что для пользователей, новичков в обоих, это будет большой фактор. Я хотел бы избежать спора, который является более интуитивным, поскольку он не имеет отношения к моему конкретному вопросу, заданному с точки зрения кого-то, с кем уже знаком data.table
. Я также хотел бы избежать дискуссии о том, как «более интуитивный» ведет к более быстрому анализу (конечно, правда, но опять же, не то, что меня больше всего интересует здесь).
Вопрос
То, что я хочу знать, это:
- Существуют ли аналитические задачи, которые намного проще кодировать с тем или иным пакетом для людей, знакомых с этими пакетами (т. Е. Требуется некоторая комбинация нажатий клавиш в сравнении с требуемым уровнем эзотерики, где меньше каждого из них - хорошая вещь).
- Существуют ли аналитические задачи, которые выполняются существенно (т.е. более чем в 2 раза) более эффективно в одном пакете по сравнению с другим.
Один недавний вопрос SO заставил меня задуматься об этом немного больше, потому что до этого момента я не думал dplyr
, что смогу предложить намного больше того, что я уже могу сделать data.table
. Вот dplyr
решение (данные в конце Q):
dat %.%
group_by(name, job) %.%
filter(job != "Boss" | year == min(year)) %.%
mutate(cumu_job2 = cumsum(job2))
Что было намного лучше, чем моя попытка взломать data.table
решение. Тем не менее, хорошие data.table
решения также довольно хороши (спасибо Жан-Роберту, Аруну, и обратите внимание, здесь я предпочел одно утверждение перед строго самым оптимальным решением):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
Синтаксис для последнего может показаться очень эзотерическим, но на самом деле он довольно прост, если вы привыкли data.table
(то есть не использовать некоторые из более эзотерических приемов).
В идеале я хотел бы увидеть несколько хороших примеров, в которых dplyr
или был бы data.table
значительно более кратким или значительно более эффективным.
Примеры
Применениеdplyr
не допускает сгруппированных операций, которые возвращают произвольное количество строк (из вопроса Эдди , обратите внимание: похоже, что это будет реализовано в dplyr 0.5 , также @beginneR показывает потенциальный обходной путь, используемыйdo
в ответе на вопрос @ eddi).data.table
поддерживает скользящие соединения (спасибо @dholstius), а также соединения с перекрытиемdata.table
внутренне оптимизирует выражение видаDT[col == value]
илиDT[col %in% values]
для скорости через автоматическую индексацию , которая использует бинарный поиск , используя тот же синтаксис базового R. Смотрите здесь для более подробной информации и крошечного теста.dplyr
предлагает стандартные оценочные версии функций (напримерregroup
,summarize_each_
), которые могут упростить программное использованиеdplyr
(обратите внимание, программное использованиеdata.table
определенно возможно, просто требует некоторого тщательного обдумывания, подстановки / цитирования и т. д., по крайней мере, насколько мне известно)
- Я запустил свои собственные тесты и обнаружил, что оба пакета сопоставимы в анализе стиля «разделение и объединение», за исключением случаев, когда существует очень большое количество групп (> 100 КБ), в этот момент
data.table
скорость существенно увеличивается. - @Arun провел несколько тестов для объединений , показав, что он
data.table
масштабируется лучше, чемdplyr
при увеличении количества групп (обновлено с учетом последних улучшений в обоих пакетах и последней версии R). Кроме того, тест при попытке получить уникальные значения имеетdata.table
~ 6 раз быстрее. - (Непроверенный) на
data.table
75% быстрее на больших версиях группы / применить / сортировать и наdplyr
40% быстрее на меньших ( еще один вопрос из комментариев , спасибо Данас). - Мэтт, главный автор
data.table
, имеет протестированные группировка операций наdata.table
,dplyr
и питонpandas
на срок до 2 миллиардов строк (~ 100GB в оперативной памяти) . - Старше тест на 80k групп имеет
data.table
~ 8x быстрее
Данные
Это первый пример, который я показал в разделе вопросов.
dat <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L), name = c("Jane", "Jane", "Jane", "Jane",
"Jane", "Jane", "Jane", "Jane", "Bob", "Bob", "Bob", "Bob", "Bob",
"Bob", "Bob", "Bob"), year = c(1980L, 1981L, 1982L, 1983L, 1984L,
1985L, 1986L, 1987L, 1985L, 1986L, 1987L, 1988L, 1989L, 1990L,
1991L, 1992L), job = c("Manager", "Manager", "Manager", "Manager",
"Manager", "Manager", "Boss", "Boss", "Manager", "Manager", "Manager",
"Boss", "Boss", "Boss", "Boss", "Boss"), job2 = c(1L, 1L, 1L,
1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L)), .Names = c("id",
"name", "year", "job", "job2"), class = "data.frame", row.names = c(NA,
-16L))
источник
dplyr
:as.data.table(dat)[, .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], by = list(name, job)]
dplyr
иdata.table
команда, и команда работают над эталонами, так что ответ будет в какой-то момент. № 2 (синтаксис) imO строго ложно, но это явно затрагивает территорию мнений, поэтому я тоже голосую за закрытие.(d)plyr
имеет меру 0dplyr
и вplyr
отношении синтаксиса, и в основном это главная причина, почему мне не нравится их синтаксис, это то, что мне нужно выучить слишком много (читай более 1) дополнительных функций (с именами, которые до сих пор не имеет смысла для меня), помните, что они делают, какие аргументы они используют и т. д. Это всегда было огромным препятствием для меня от философии plyr..SD
). [серьезно] Я думаю, что это законные конструктивные отличия, которые понравятся разным людямОтветы:
Мы должны охватывать по крайней мере , эти аспекты , чтобы обеспечить всесторонний ответ / сравнения (в произвольном порядке важности):
Speed
,Memory usage
,Syntax
иFeatures
.Мое намерение состоит в том, чтобы охватить каждый из них как можно более четко с точки зрения таблицы данных.
Синтаксис data.table согласован в своей форме -
DT[i, j, by]
. Чтобы сохранитьi
,j
иby
вместе это дизайн. Объединяя связанные операции, он позволяет легко оптимизировать операции для скорости и, что более важно, использования памяти , а также предоставляет некоторые мощные функции , сохраняя при этом согласованность синтаксиса.1. Скорость
К вопросу, уже показывающему, что data.table становится быстрее, чем dplyr, добавляется довольно много тестов (хотя в основном это касается операций группирования), в том числе число групп и / или строк, которые нужно сгруппировать, увеличивается, включая тесты Matt для группировки с 10 миллионов до 2 миллиарда строк (100 ГБ в ОЗУ) на 100 - 10 миллионов групп и различные столбцы группировки, которые также сравниваются
pandas
. Смотрите также обновленные тесты , которые включаютSpark
иpydatatable
также.В тестах было бы замечательно охватить и эти оставшиеся аспекты:
Группировка операций, включающая подмножество строк, т.
DT[x > val, sum(y), by = z]
Е. Операции типа.Оцените другие операции, такие как обновление и присоединения .
Кроме того, тест памяти для каждой операции в дополнение к времени выполнения.
2. Использование памяти
Операции с участием
filter()
илиslice()
в dplyr могут быть неэффективными в памяти (как для data.frames, так и для data.tables). Смотрите этот пост .Интерфейс data.table в данный момент позволяет изменять / обновлять столбцы по ссылке (обратите внимание, что нам не нужно повторно присваивать результат обратно переменной).
Но dplyr никогда не будет обновляться по ссылке. Эквивалент dplyr будет (обратите внимание, что результат должен быть переназначен):
Забота об этом - ссылочная прозрачность . Обновление объекта data.table по ссылке, особенно внутри функции, не всегда желательно. Но это невероятно полезная функция: см. Этот и этот пост для интересных случаев. И мы хотим сохранить это.
Поэтому мы работаем над экспортом
shallow()
функции в data.table, которая предоставит пользователю обе возможности . Например, если желательно не изменять входную таблицу data.table внутри функции, можно выполнить:Не используя
shallow()
, старые функциональные возможности сохраняются:Создавая поверхностную копию с помощью
shallow()
, мы понимаем, что вы не хотите изменять исходный объект. Мы позаботимся обо всем внутренне, чтобы гарантировать, что при копировании столбцов вы изменяете только тогда, когда это абсолютно необходимо . Когда это реализовано, это должно полностью решить проблему ссылочной прозрачности , предоставляя пользователю обе возможности.Агрегировать при присоединении:
Предположим, у вас есть две таблицы данных:
И вы хотели бы получить
sum(z) * mul
для каждой строкиDT2
при объединении по столбцамx,y
. Мы можем либо:1) совокупность,
DT1
чтобы получитьsum(z)
, 2) выполнить объединение и 3) умножить (или)2) сделать все за один раз (используя
by = .EACHI
функцию):В чем преимущество?
Нам не нужно выделять память для промежуточного результата.
Нам не нужно группировать / хэшировать дважды (один для агрегации, другой для объединения).
И что более важно, операция, которую мы хотели выполнить, понятна из
j
(2).Проверьте этот пост для подробного объяснения
by = .EACHI
. Промежуточные результаты не материализуются, и объединение + агрегат выполняется за один раз.Посмотрите на это , это и это сообщения для реальных сценариев использования.
Вначале
dplyr
вам придется объединять и агрегировать или агрегировать, а затем объединять , но ни один из них не является настолько эффективным с точки зрения памяти (что, в свою очередь, приводит к скорости).Обновление и присоединения:
Рассмотрим код data.table, показанный ниже:
добавляет / обновляет
DT1
столбецcol
сmul
изDT2
тех строк, гдеDT2
совпадает ключевой столбецDT1
. Я не думаю, что есть точный эквивалент этой операцииdplyr
, то есть, не избегая*_join
операции, которая должна была бы копировать весь,DT1
только чтобы добавить в нее новый столбец, что не нужно.Проверьте этот пост для реального сценария использования.
3. Синтаксис
Давайте теперь посмотрим на синтаксис . Хэдли прокомментировал здесь :
Я считаю это замечание бессмысленным, потому что оно очень субъективно. Возможно, мы можем попытаться противопоставить последовательность в синтаксисе . Мы будем сравнивать синтаксис data.table и dplyr бок о бок.
Мы будем работать с фиктивными данными, показанными ниже:
Основные операции агрегации / обновления.
Синтаксис data.table компактен и довольно многословен. Вещи более или менее эквивалентны в случае (а).
В случае (b) мы должны были использовать
filter()
dplyr при суммировании . Но при обновлении нам пришлось переместить логику внутрьmutate()
. Однако в data.table мы выражаем обе операции с помощью одной и той же логики - работаем со строками, гдеx > 2
, но в первом случае, получаемsum(y)
, тогда как во втором случае обновляем эти строкиy
своей совокупной суммой.Это то, что мы имеем в виду, когда говорим, что
DT[i, j, by]
форма последовательна .Аналогично в случае (c), когда у нас есть
if-else
условие, мы можем выразить логику «как есть» как в data.table, так и в dplyr. Однако, если мы хотим вернуть только те строки, в которых выполняетсяif
условие, и пропустить иначе, мы не можем использоватьsummarise()
напрямую (AFAICT). Мы должныfilter()
сначала, а затем подвести итог, потому чтоsummarise()
всегда ожидает единственное значение .Хотя он возвращает тот же результат, использование
filter()
здесь делает фактическую операцию менее очевидной.Вполне возможно, что можно использовать и
filter()
в первом случае (мне это не кажется очевидным), но я хочу сказать, что мы не должны этого делать.Агрегирование / обновление по нескольким столбцам
В случае (а) коды более или менее эквивалентны. data.table использует знакомую базовую функцию
lapply()
, в то время какdplyr
вводит*_each()
вместе с набором функцийfuns()
.Для data.table
:=
необходимо указать имена столбцов, тогда как dplyr генерирует их автоматически.В случае (b) синтаксис dplyr относительно прост. Улучшение агрегации / обновления для нескольких функций находится в списке data.table.
В случае (с), однако, dplyr будет возвращать
n()
столько раз, сколько столбцов, а не только один раз. В data.table все, что нам нужно сделать, это вернуть список вj
. Каждый элемент списка станет столбцом в результате. Итак, мы можем снова использовать знакомую базовую функциюc()
для конкатенации.N
к a,list
которая возвращает alist
.присоединяется
dplyr предоставляет отдельные функции для каждого типа объединения, где data.table позволяет выполнять соединения с использованием одного
DT[i, j, by]
и того же синтаксиса (и с указанием причины). Он также предоставляет эквивалентнуюmerge.data.table()
функцию в качестве альтернативы.Некоторые могут найти отдельную функцию для каждого объединения гораздо лучше (левый, правый, внутренний, анти, полу и т. Д.), Тогда как другим могут понравиться data.table's
DT[i, j, by]
илиmerge()
которая похожа на базу R.Однако соединения dplyr делают именно это. Ничего больше. Не меньше.
data.tables может выбирать столбцы при присоединении (2), и в dplyr вам нужно
select()
сначала выполнить оба data.frames, прежде чем присоединиться, как показано выше. В противном случае вы бы материализовали объединение ненужными столбцами, чтобы потом удалить их, а это неэффективно.data.tables может объединяться при присоединении (3), а также обновляться при присоединении (4), используя
by = .EACHI
функцию. Зачем использовать весь результат объединения, чтобы добавить / обновить всего несколько столбцов?data.table может катить соединения (5) - крен вперед, LOCF , крен назад, NOCB , ближайший .
data.table также имеет
mult =
аргумент, который выбирает первое , последнее или все совпадения (6).data.table имеет
allow.cartesian = TRUE
аргумент для защиты от случайных недопустимых объединений.do()
...Суммирование dplyr специально разработано для функций, которые возвращают одно значение. Если ваша функция возвращает несколько / неравные значения, вам придется прибегнуть к
do()
. Вы должны знать заранее обо всех возвращаемых значениях ваших функций..SD
эквивалент.
В data.table вы можете добавить что угодно
j
- единственное, что нужно помнить, это вернуть список, чтобы каждый элемент списка был преобразован в столбец.В dplyr не может этого сделать. Приходится прибегать к
do()
зависимости от того, насколько вы уверены в том, будет ли ваша функция всегда возвращать одно значение. И это довольно медленно.Посмотрите на этот ТАК вопрос и этот . Интересно, можно ли выразить ответ как простой, используя синтаксис dplyr ...
4. Особенности
Я указал на большинство функций здесь, а также в этом посте. К тому же:
fread - быстрый файловый ридер уже давно доступен.
fwrite - теперь доступен параллельный быстрый файловый редактор. Смотрите этот пост для подробного объяснения реализации и № 1664 для отслеживания дальнейших событий.
Автоматическая индексация - еще одна удобная функция для оптимизации базового синтаксиса R, как есть, внутри.
Специальная группировка :
dplyr
автоматически сортирует результаты, группируя переменные во времяsummarise()
, что может быть не всегда желательно.Многочисленные преимущества в соединениях data.table (для скорости / эффективности памяти и синтаксиса), упомянутые выше.
Неэквивалентные объединения : Позволяет объединениям использовать другие операторы
<=, <, >, >=
наряду со всеми другими преимуществами соединений data.table.Перекрывающиеся объединения диапазонов были недавно реализованы в data.table. Проверьте этот пост для обзора с тестами.
setorder()
функция в data.table, которая позволяет действительно быстро переупорядочивать data.tables по ссылке.dplyr предоставляет интерфейс для баз данных, используя тот же синтаксис, который в настоящее время отсутствует в data.table.
data.table
обеспечивает более эквиваленты множественных операций (написанный Ян Горецкий) -fsetdiff
,fintersect
,funion
иfsetequal
с дополнительнымall
аргументом (как в SQL).data.table загружается чисто без предупреждений о маскировании и имеет механизм, описанный здесь для
[.data.frame
совместимости при передаче в любой пакет R. dplyr изменяет базовые функцииfilter
,lag
и[
которые могут вызвать проблемы; например, здесь и здесь .В заключение:
В отношении баз данных - нет причин, по которым data.table не может предоставить аналогичный интерфейс, но сейчас это не является приоритетом. Это может быть усилено, если пользователям очень понравится эта функция ... не уверен.
На параллелизме - все сложно, пока кто-то не пойдет и не сделает это. Конечно это потребует усилий (будучи потокобезопасным).
OpenMP
.источник
:=
),dplyr
эквивалент должен также использовать<-
как вDF <- DF %>% mutate...
вместо простоDF %>% mutate...
dplyr
может быть проще для пользователей, которые привыкли кplyr
синтаксису, ноdata.table
может быть проще для пользователей, которые раньше запрашивали синтаксис языковSQL
и реляционную алгебру, лежащую в основе этого, что все о преобразовании табличных данных. @ Arun, вы должны заметить, что операторы множеств очень легко выполнимы с помощьюdata.table
функции обтекания и, конечно, значительно ускоряют работу.Вот моя попытка получить исчерпывающий ответ с точки зрения dplyr, следуя широкому плану ответа Аруна (но несколько перестроенному на основе различных приоритетов).
Синтаксис
В синтаксисе есть некоторая субъективность, но я придерживаюсь своего утверждения о том, что сжатость data.table усложняет изучение и чтение. Это отчасти потому, что dplyr решает гораздо более легкую проблему!
Одна действительно важная вещь, которую dplyr делает для вас, это то, что ограничивает ваши возможности. Я утверждаю, что большинство проблем с одной таблицей можно решить с помощью всего пяти ключевых глаголов, которые фильтруют, выбирают, изменяют, упорядочивают и суммируют, а также наречие «по группам». Это ограничение очень помогает, когда вы изучаете манипулирование данными, потому что оно помогает упорядочить ваше представление о проблеме. В dplyr каждый из этих глаголов отображается на одну функцию. Каждая функция выполняет одну работу, и ее легко понять в отдельности.
Вы создаете сложность, связывая эти простые операции с
%>%
. Вот пример одного из постов Arun , связанных с :Даже если вы никогда раньше не видели dplyr (или даже R!), Вы все равно можете понять суть происходящего, потому что все функции - это английские глаголы. Недостаток английских глаголов заключается в том, что они требуют большего набора текста, чем
[
, но я думаю, что это может быть в значительной степени смягчено лучшим автозаполнением.Вот эквивалентный код data.table:
Сложнее следовать этому коду, если вы уже не знакомы с data.table. (Я также не мог понять, как сделать отступ для повторения
[
так, чтобы это выглядело хорошо на мой взгляд). Лично, когда я смотрю на код, который написал 6 месяцев назад, это все равно, что смотреть на код, написанный незнакомцем, поэтому я предпочел простой, хотя и многословный, код.Два других незначительных фактора, которые, я думаю, немного снижают читабельность:
Поскольку почти каждая операция с таблицей данных использует
[
дополнительный контекст, чтобы выяснить, что происходит. Например,x[y]
объединяет ли две таблицы данных или извлекает столбцы из фрейма данных? Это только небольшая проблема, потому что в хорошо написанном коде имена переменных должны подсказывать, что происходит.Мне нравится, что
group_by()
это отдельная операция в dplyr. Это в корне меняет вычисления, поэтому я думаю, что это должно быть очевидно при просмотре кода, и его легче обнаружить,group_by()
чемby
аргумент[.data.table
.Мне также нравится, что труба не ограничивается только одной упаковкой. Вы можете начать, приводя в порядок свои данные с помощью tidyr , и заканчивая графиком в ggvis . И вы не ограничены пакетами, которые я пишу - любой может написать функцию, которая образует бесшовную часть канала манипулирования данными. На самом деле, я предпочитаю предыдущий код data.table, переписанный с помощью
%>%
:И идея обвязки
%>%
не ограничивается только фреймами данных и легко обобщается для других контекстов: интерактивной веб-графики , просмотра веб-страниц , сущностей , контрактов во время выполнения , ...)Память и производительность
Я смешал их вместе, потому что для меня они не так важны. Большинство пользователей R работают с менее чем 1 миллионом строк данных, и dplyr достаточно быстр для того объема данных, который вы не знаете о времени обработки. Мы оптимизируем dplyr для выразительности на средних данных; не стесняйтесь использовать data.table для быстрой обработки больших данных.
Гибкость dplyr также означает, что вы можете легко настроить характеристики производительности, используя тот же синтаксис. Если производительность dplyr с бэкэндом фрейма данных недостаточна для вас, вы можете использовать бэкэнд data.table (хотя и с несколько ограниченным набором функций). Если данные, с которыми вы работаете, не помещаются в память, вы можете использовать базу данных базы данных.
Все это говорит о том, что производительность dplyr улучшится в долгосрочной перспективе. Мы определенно воплотим в жизнь некоторые из замечательных идей data.table, такие как упорядочение по осям и использование того же индекса для объединений и фильтров. Мы также работаем над распараллеливанием, чтобы мы могли использовать преимущества нескольких ядер.
особенности
Несколько вещей, над которыми мы планируем работать в 2015 году:
readr
пакет, чтобы сделать его легко получить файлы с диска , так и в памяти, аналогичноfread()
.Более гибкие объединения, в том числе поддержка неэквивалентных.
Более гибкая группировка, например, образцы начальной загрузки, накопительные пакеты и многое другое
Я также вкладываю время в улучшение коннекторов базы данных R , в возможность общения с веб-интерфейсом API и упрощение работы с HTML-страницами .
источник
data.table
синтаксис), но вы можете легко использовать их%>%
для конвейерной обработки,data.table
если вам не нравится[
стиль.%>%
не является специфическим дляdplyr
, скорее идет из отдельного пакета (который вы тоже являетесь соавтором), поэтому я не уверен, что понимаю, что вы пытаетесь сказать в большей части вашего параграфа « Синтаксис» .%>%
с data.tableDT[\n\texpression\n][\texpression\n]
( суть ), на самом деле работает довольно хорошо. Я держу ответ Аруна как ответ, так как он более прямо отвечает на мои конкретные вопросы, которые не столько касаются доступности синтаксиса, но я думаю, что это хороший ответ для людей, пытающихся получить общее представление о различиях / общностях междуdplyr
иdata.table
,fread()
? Не лучше ли тратить время на улучшение fread () или на другие (недостаточно развитые) вещи?data.table
основан на массовом злоупотреблении[]
нотацией. Это его самая большая сила и самая большая слабость.В прямом ответе на заголовок вопроса ...
dplyr
определенно делает то, чтоdata.table
не может.Ваша точка № 3
является прямым ответом на ваш собственный вопрос, но не повышен до достаточно высокого уровня.
dplyr
действительно расширяемый интерфейс для нескольких механизмов хранения данных, где, какdata.table
является расширением для одного.Рассматривайте
dplyr
как внутренний независимый интерфейс со всеми целями, использующими один и тот же грамматик, где вы можете расширять цели и обработчики по своему желанию.data.table
сdplyr
точки зрения, одна из тех целей.Вы никогда (я надеюсь) не увидите день, когда вы
data.table
попытаетесь перевести ваши запросы для создания операторов SQL, которые работают с хранилищами данных на диске или в сети.dplyr
может возможно делать вещиdata.table
не хочет или не может делать так же хорошо.Основываясь на дизайне работы в памяти,
data.table
может быть гораздо сложнее заняться параллельной обработкой запросов, чемdplyr
.В ответ на вопросы в теле ...
Применение
Это может показаться пунтом, но реальный ответ - нет. Люди знакомые с инструментами, похоже, используют либо тот, который им наиболее знаком, либо тот, который на самом деле подходит для данной работы. С учетом вышесказанного, иногда вы хотите представить определенную читаемость, иногда уровень производительности, а когда вам нужен достаточно высокий уровень обоих, вам может просто понадобиться другой инструмент, чтобы идти вместе с тем, что у вас уже есть, чтобы сделать более четкие абстракции ,
Представление
Опять нет.
data.table
превосходит эффективность во всем, что делает, гдеdplyr
в некоторых отношениях становится бременем быть ограниченным базовым хранилищем данных и зарегистрированными обработчиками.Это означает, что когда вы сталкиваетесь с проблемой производительности,
data.table
вы можете быть уверены, что она есть в вашей функции запроса, и если это на самом деле узкое место,data.table
тогда вы выиграли радость подачи отчета. Это также верно, когдаdplyr
используетсяdata.table
как бэкэнд; Вы можете увидеть некоторые накладные расходы,dplyr
но есть вероятность, что это ваш запрос.Когда
dplyr
есть проблемы с производительностью с back-endами, вы можете обойти их, зарегистрировав функцию для гибридной оценки или (в случае баз данных) манипулируя сгенерированным запросом перед выполнением.Также смотрите принятый ответ, когда plyr лучше data.table?
источник