Огляд
Я відносно знайомий data.table, не так вже й багато dplyr. Я прочитав кілька dplyrвіньєт та прикладів, які з’явились на SO, і поки що мої висновки:
data.tableіdplyrвони порівнянні за швидкістю, за винятком випадків, коли існує багато (тобто> 10-100 К) груп, а також за інших обставин (див. орієнтири нижче)dplyrмає більш доступний синтаксисdplyrконспекти (або заповіти) потенційних взаємодій з БД- Існують деякі незначні відмінності функціональності (див. "Приклади / використання" нижче)
На мій погляд 2. не має великої ваги, тому що я досить добре знайомий з цим data.table, хоча я розумію, що для нових користувачів це буде великим фактором. Я хотів би уникнути аргументації щодо того, який є більш інтуїтивним, оскільки це не має значення для мого конкретного питання, заданого з точки зору когось уже знайомого data.table. Я також хотів би уникнути дискусії про те, як "більш інтуїтивно зрозумілий" призводить до більш швидкого аналізу (безумовно, правда, але знову ж таки, не те, що мене найбільше цікавить тут).
Питання
Що я хочу знати:
- Чи є аналітичні завдання, які набагато простіше кодувати тим чи іншим пакетом для людей, знайомих з пакунками (тобто, якась комбінація натискань клавіш, необхідна в порівнянні з необхідним рівнем езотерики, де менше кожного - це добре).
- Чи є аналітичні завдання, які виконуються суттєво (тобто більше ніж 2 рази) ефективніше в одному пакеті проти іншого.
Одне з останніх запитань про так змусило мене подумати про це трохи більше, тому що до цього моменту я не думав, 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не дозволяє групувати операції, які повертають довільну кількість рядків (із запитання 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.table6 разів швидше. - (Неперевірений) на
data.table75% швидше на більших версіях групи / застосувати / сортувати, тоді якdplyrна менших на 40% швидше ( ще одне питання щодо коментарів , дякую сьогодні). - Метт, головний автор програми
data.table, має орієнтовані операції групуванняdata.table,dplyrа пітонpandas- до 2 мільярдів рядків (~ 100 ГБ оперативної пам’яті) . - Старше тест на 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і data.tableкоманди, і команди працюють над еталонами, тому відповідь буде в якийсь момент. # 2 (синтаксис) imO суворо помилково, але це явно заходить на територію думок, тому я голосую також за те, щоб закрити.
(d)plyrмає міру 0
dplyrі plyrщодо синтаксису, і в основному є основною причиною, чому мені не подобається їх синтаксис, - це те, що мені доведеться навчитися занадто багато (читати більше 1) додаткових функцій (з іменами, які все ще не майте сенсу для мене), пам’ятайте, що вони роблять, які аргументи вони приймають тощо. Це завжди було величезним відключенням для мене від філософії plyr.
.SD). [серйозно] Я думаю, що це законні відмінності дизайну, які сподобаються різним людям
dplyrце:as.data.table(dat)[, .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], by = list(name, job)]