Обзор
Я относительно знаком с 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
был значительно более кратким или работал значительно лучше.
Примеры
Usagedplyr
не разрешает сгруппированные операции, возвращающие произвольное количество строк (из вопрос eddi, примечание: похоже, это будет реализовано в 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% быстрее в меньших (еще один ТАК вопрос из комментариев, спасибо, danas). - Мэтт, главный автор
data.table
, провел сравнительный анализ операций группировки наdata.table
,dplyr
и pythonpandas
до 2 миллиардов строк (~ 100 ГБ ОЗУ). - старый тест для 80 000 групп показал
data.table
~ 8 раз быстрее
Данные
Это первый пример, который я показал в разделе вопросов.
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)]
- person eddi   schedule 29.01.2014dplyr
иdata.table
работают над тестами, поэтому в какой-то момент ответ будет. # 2 (синтаксис) imO строго неверно, но это явно выходит на территорию мнений, поэтому я тоже голосую за закрытие. - person eddi   schedule 29.01.2014(d)plyr
, имеет меру 0 - person eddi   schedule 29.01.2014dplyr
, чтобы исключить его, и мне было любопытно, может ли кто-нибудь придумать хороший контрпример. Кроме того, приятное упрощение формулировкиdata.table
. - person BrodieG   schedule 29.01.2014plyr
иdata.table
и также был закрыт. Мой ответ здесь объясняет, почему это больше. - person Brian Diggs   schedule 29.01.2014data.table
, имеет меру 0, но это не противоречит вашему мнению;) - person hadley   schedule 29.01.2014data.table
присоединений в конце? И (вероятно, повторяя очевидное, изложенное в другом месте) как насчет более интересных размеров данных (где я бы определил интересное как что-то, что занимает больше минуты в базе - что обычно является основной причиной, по которой люди начинают изучать тесты пакетов)? - person eddi   schedule 30.01.2014dplyr
, так иplyr
, и, по сути, является основной причиной того, что мне не нравится их синтаксис, заключается в том, что мне нужно выучить слишком много (читайте более 1) дополнительных функций (с именами что все еще не имеют для меня смысла), помните, что они делают, какие аргументы приводят и т. д. Это всегда сильно отталкивало меня от философии plyr. - person eddi   schedule 30.01.2014.SD
). [серьезно] Я думаю, что это законные различия в дизайне, которые понравятся разным людям - person hadley   schedule 30.01.2014.SD
et al - это справедливо -.SD
мне потребовалось немного времени, чтобы понять, но к тому времени, когда я добрался до этого, я уже был в состоянии сделать много, в то время как (d) plyr представляет вам большой барьер прямо перед собой. - person eddi   schedule 30.01.2014dplyr
иdata.table
. - person danas.zuokas   schedule 31.01.2014data.table
, он намного менее подробен, чем стандартный фрейм данных, и большинство операций выполняется быстрее. Это заставляет вас думать векторным мышлением (что дает более высокую производительность). Я считаю это хорошей заменой фрейма данных. Синтаксис сначала не был интуитивно понятным, но как только вы начнете его использовать, его легко запомнить. Я вижуdplyr
как набор функций, ноdata.table
как новый объект класса с гораздо более высокой производительностью и кратким синтаксисом, чем традиционный фрейм данных. - person David Leal   schedule 15.03.2017