Должен ли я инвестировать свои усилия в обучение для обработки данных в R, особенно между dplyr
, dtplyr
и data.table
?
Я использую в
dplyr
основном, но когда данные слишком велики для этого, я буду использоватьdata.table
, что встречается редко. Итак, теперь, когдаdtplyr
v1.0 вышел в качестве интерфейсаdata.table
, на первый взгляд кажется, что мне больше не нужно беспокоиться об использованииdata.table
интерфейса.Итак, какие наиболее полезные функции или аспекты
data.table
этого нельзя сделатьdtplyr
в данный момент, и что, скорее всего, никогда не будет сделаноdtplyr
?На первый взгляд,
dplyr
с преимуществамиdata.table
звучит как будтоdtplyr
обгонитdplyr
. Будет ли какая-либо причина для использования,dplyr
когдаdtplyr
она полностью созреет?
Примечание: я не спрашиваю о dplyr
vs data.table
(как в data.table vs dplyr: один может делать что-то хорошо, другой не может или плохо? ), Но, учитывая, что один предпочтительнее другого для конкретной проблемы, почему бы не т dtplyr
быть инструментом для использования.
источник
dplyr
котором вы не можете преуспетьdata.table
? Если нет, переключениеdata.table
будет лучше, чемdtplyr
.dtplyr
файла readme: «Некоторыеdata.table
выражения не имеют прямогоdplyr
эквивалента. Например, нет возможности выразить перекрестные или переходные соединения с помощьюdplyr
. ' и «Чтобы соответствоватьdplyr
семантике,mutate
() не изменяется на месте по умолчанию. Это означает, что большинство задействованных выраженийmutate()
должны делать копии, которые не были бы необходимы, если бы вы использовалиdata.table
напрямую ». Во второй части есть обходной путь, но, учитывая частотуmutate
его использования, это довольно большой недостаток в моих глазах.Ответы:
Я постараюсь дать мои лучшие руководства, но это не легко, потому что нужно знать все {data.table}, {dplyr}, {dtplyr}, а также {base R}. Я использую {data.table} и много пакетов {tidy-world} (кроме {dplyr}). Люблю оба, хотя я предпочитаю синтаксис data.table dplyr. Я надеюсь, что все пакеты tidy-world будут использовать {dtplyr} или {data.table} в качестве бэкэнда, когда это будет необходимо.
Как и в случае любого другого перевода (например, dplyr-to-sparkly / SQL), есть вещи, которые можно или нельзя перевести, по крайней мере, на данный момент. Я имею в виду, может быть, однажды {dtplyr} сможет сделать перевод на 100%, кто знает. Приведенный ниже список не является исчерпывающим и не является на 100% правильным, так как я постараюсь ответить наилучшим образом, основываясь на моих знаниях по смежным темам / пакетам / вопросам / и т. Д.
Важно отметить, что для тех ответов, которые не совсем точны, я надеюсь, что это даст вам некоторые рекомендации о том, на какие аспекты {data.table} вы должны обратить внимание, и сравните его с {dtplyr} и выясните ответы самостоятельно. Не принимайте эти ответы как должное.
И я надеюсь, что этот пост можно использовать как один из ресурсов для всех пользователей / создателей {dplyr}, {data.table} или {dtplyr} для обсуждений и совместной работы, а также для улучшения #RStats.
{data.table} используется не только для быстрых и эффективных операций с памятью. Многие люди, включая меня, предпочитают элегантный синтаксис {data.table}. Он также включает в себя другие быстрые операции, такие как функции временных рядов, такие как скользящее семейство (то есть
frollapply
), написанные на C. Он может использоваться с любыми функциями, включая Tidyverse. Я использую {data.table} + {purrr} много!Сложность операций
Это можно легко перевести
{data.table} очень быстрый и эффективно использует память, потому что (почти?) все построено с нуля из C с ключевыми понятиями « обновление по ссылке , ключ (думаю, SQL)» и их постоянная оптимизация повсюду в пакете (то есть
fifelse
,fread/fread
, радикс порядок сортировки принят базовый R), а убедившись , что синтаксис кратким и последовательным, поэтому я думаю , что это элегантно.От введения в data.table основные операции с данными, такие как подмножество, группа, обновление, объединение и т. Д. , Хранятся вместе для
краткий и непротиворечивый синтаксис ...
выполнять анализ плавно без когнитивного бремени необходимости отображать каждую операцию ...
автоматическая внутренняя и очень эффективная оптимизация операций за счет точного знания данных, необходимых для каждой операции, что приводит к очень быстрому и эффективному коду кода
Последний пункт, как пример,
Учитывая это, чтобы воспользоваться преимуществами {data.table}, перевод {dtplr} должен быть правильным в этом отношении. Чем сложнее операции, тем сложнее переводы. Для простых операций, как указано выше, это, безусловно, можно легко перевести. Для сложных или тех, которые не поддерживаются {dtplyr}, вы должны выяснить себя, как упомянуто выше, нужно сравнить переведенный синтаксис и тест и ознакомиться с соответствующими пакетами.
Для сложных операций или неподдерживаемых операций я мог бы привести несколько примеров ниже. Опять же, я просто стараюсь изо всех сил. Будьте нежны со мной.
Обновление по ссылке
Я не буду вдаваться в подробности, но вот несколько ссылок
Основной ресурс: Ссылочная семантика
Более подробная информация: точно знать, когда data.table является ссылкой (против копии) другой data.table
Обновление по ссылке , на мой взгляд, самая важная особенность {data.table}, и это делает его таким быстрым и эффективным для памяти.
dplyr::mutate
не поддерживает его по умолчанию. Поскольку я не знаком с {dtplyr}, я не уверен, сколько и какие операции могут или не могут поддерживаться {dtplyr}. Как упоминалось выше, это также зависит от сложности операций, которые, в свою очередь, влияют на переводы.Есть два способа использовать обновление по ссылке в {data.table}
оператор присваивания {data.table}
:=
set
-семейством:set
,setnames
,setcolorder
,setkey
,setDT
,fsetdiff
, и многое другое:=
чаще используется по сравнению сset
. Для сложного и большого набора данных, обновление по ссылке является ключом к максимальной скорости и эффективности использования памяти. Простой способ мышления (не на 100% точный, поскольку детали намного сложнее, чем это, поскольку он включает в себя твердое / мелкое копирование и многие другие факторы), скажем, вы имеете дело с большим набором данных размером 10 ГБ, с 10 столбцами и 1 ГБ каждый , Чтобы манипулировать одним столбцом, вам нужно иметь дело только с 1 ГБ.Ключевым моментом является то, что при обновлении по ссылке вам нужно иметь дело только с необходимыми данными. Вот почему при использовании {data.table}, особенно при работе с большим набором данных, мы всегда используем обновление по ссылке, когда это возможно. Например, манипулирование большим набором данных моделирования
Операция вложенности
list(.SD)
может не поддерживаться {dtlyr}, поскольку пользователи tidyverse используютtidyr::nest
? Поэтому я не уверен, что последующие операции можно перевести как способ {data.table} быстрее и меньше памяти.ПРИМЕЧАНИЕ: результат data.table находится в «миллисекундах», dplyr в «минутах»
Есть много вариантов использования обновления по ссылке и даже пользователи {data.table} не будут постоянно использовать его расширенную версию, так как для этого требуется больше кодов. Независимо от того, поддерживает ли {dtplyr} это "из коробки", вы должны выяснить сами.
Многократное обновление по ссылке для одинаковых функций
Основной ресурс: элегантное назначение нескольких столбцов в data.table с помощью lapply ()
Это включает в себя либо наиболее часто используемые
:=
илиset
.По словам создателя {data.table} Мэтта Доула
Присоединяйтесь + setkey + обновление по ссылке
В последнее время мне нужно было быстрое соединение с относительно большими данными и похожими шаблонами соединения, поэтому я использую силу обновления по ссылке вместо обычных объединений. Поскольку им требуется больше кодов, я обертываю их в закрытый пакет с нестандартной оценкой для повторного использования и удобочитаемости, где я это называю
setjoin
.Я сделал некоторые тесты здесь: data.table join + обновление по ссылке + setkey
Резюме
ПРИМЕЧАНИЕ:
dplyr::left_join
также был протестирован и является самым медленным с ~ 9000 мс, использует больше памяти, чем оба {data.table}update_by_reference
иsetkey_n_update
, но использует меньше памяти, чем normal_join {data.table}. Он занимал около 2,0 ГБ памяти. Я не включил его, поскольку хочу сосредоточиться исключительно на {data.table}.Основные результаты
setkey + update
иupdate
в ~ 11 и ~ 6,5 раз быстрее, чемnormal join
соответственноsetkey + update
аналогична тем,update
что накладные расходы вsetkey
значительной степени компенсируют собственное повышение производительностиsetkey
это не требуется,setkey + update
быстрее, чемupdate
в ~ 1,8 раза (или быстрее, чемnormal join
в ~ 11 раз)Примеры
Для соединений с высокой производительностью и эффективностью использования памяти используйте либо,
update
либоsetkey + update
, если последнее выполняется быстрее за счет большего количества кодов.Давайте рассмотрим некоторые псевдокоды , для краткости. Логика одинаковая.
Для одного или нескольких столбцов
Для многих столбцов
Обертка для быстрого и эффективного использования памяти ... многие из них ... с одинаковым шаблоном соединения, оберните их, как
setjoin
описано выше - сupdate
- с или безsetkey
С
setkey
аргументомon
можно опустить. Он также может быть включен для удобства чтения, особенно для сотрудничества с другими.Большой ряд операций
set
setkey
)Связанный ресурс: добавьте строку по ссылке в конце объекта data.table
Резюме обновления по ссылке
Это всего лишь несколько случаев использования обновления по ссылке . Есть много других.
Как вы можете видеть, для расширенного использования при работе с большими данными существует множество вариантов использования и методов, использующих обновление по ссылке для большого набора данных. Это не так просто использовать в {data.table}, и если {dtplyr} поддерживает это, вы можете узнать сами.
В этом посте я остановлюсь на обновлении по ссылке, так как считаю, что это самая мощная функция {data.table} для быстрой и эффективной работы с памятью. Тем не менее, есть много, много других аспектов, которые делают его таким эффективным, и я думаю, что он не поддерживается {dtplyr}.
Другие ключевые аспекты
Что поддерживается / не поддерживается, это также зависит от сложности операций и от того, включает ли это встроенную функцию data.table, такую как обновление по ссылке или
setkey
. И является ли переведенный код более эффективным (тот, который пишут пользователи data.table), также является еще одним фактором (т. Е. Код переведен, но является ли он эффективной версией?). Многие вещи взаимосвязаны.setkey
, См Ключи и быстрый набор на основе двоичного поискаfrollapply
. функции качения, подвижные агрегаты, раздвижное окно, скользящее среднееi
,j
илиby
операций (вы можете использовать практически любые выражения в там), я думаю , тем труднее переводы, особенно когда она сочетается с обновлением по ссылке ,setkey
и другим родной data.table функции какfrollapply
stringr::str_*
семейства и базы R, и нахожу, что базы R в некоторой степени быстрее и используют их. Дело в том, что не оставляйте себя только на tidyverse или data.table или ..., изучите другие варианты, чтобы выполнить работу.Многие из этих аспектов взаимосвязаны с пунктами, упомянутыми выше
сложность операций
обновление по ссылке
Вы можете узнать, поддерживают ли {dtplyr} эти операции, особенно когда они объединены.
Еще один полезный прием при работе с маленьким или большим набором данных во время интерактивного сеанса {data.table} действительно оправдывает свое обещание значительно сократить время программирования и вычислений .
Установка ключа для постоянно используемой переменной как для скорости, так и для «перегруженных имен строк» (подмножество без указания имени переменной).
Если ваши операции включают только простые, как в первом примере, {dtplyr} может выполнить работу. Для сложных / неподдерживаемых вы можете использовать это руководство, чтобы сравнить переведенные {dtplyr} с тем, как опытные пользователи data.table будут быстро и эффективно кодировать код с элегантным синтаксисом data.table. Перевод не означает, что это самый эффективный способ, так как могут быть разные методы для обработки больших объемов данных. Для еще большего набора данных вы можете объединить {data.table} с {disk.frame} , {fst} и {drake} и другими удивительными пакетами, чтобы получить лучшее из этого. Существует также {big.data.table}, но в настоящее время он неактивен.
Надеюсь, это поможет всем. Хорошего дня ☺☺
источник
На ум приходят неуравновешенные и подвижные соединения. Похоже, что нет никаких планов по включению эквивалентных функций в dplyr, поэтому dtplyr ничего не нужно переводить.
Также есть изменение формы (оптимизированный dcast и melt, эквивалентный тем же функциям в reshape2), которого нет и в dplyr.
Все функции * _if и * _at в настоящее время также не могут быть переведены с помощью dtplyr, но они находятся в разработке.
источник
Обновление столбца при соединении. Некоторые трюки .SD. Многие функции f. И Бог знает, что еще, потому что #rdatatable - это больше, чем просто библиотека, и ее нельзя суммировать с помощью нескольких функций.
Это целая экосистема сама по себе
Мне никогда не был нужен dplyr с того дня, как я начал R. Поскольку data.table чертовски хорош
источник