обзор
Я относительно знаком с data.table
, не так много с dplyr
. Я прочитал некоторые виньетки и примеры dplyr
на SO, и пока мои выводы таковы:
-
data.table
иdplyr
сопоставимы по скорости, за исключением случаев, когда существует много (то есть> 10-100 КБ) групп, и в некоторых других обстоятельствах (см. контрольные показатели ниже) -
dplyr
более доступный синтаксис -
dplyr
рефераты (или будут) потенциальные взаимодействия с БД - Есть некоторые незначительные функциональные различия (см. "Примеры/Использование" ниже)
На мой взгляд, 2. не имеет большого веса, потому что я достаточно хорошо знаком с этим data.table
, хотя я понимаю, что для пользователей, data.table
знакомых с data.table
, это будет большой фактор. Я хотел бы избежать спора, который является более интуитивным, поскольку он не имеет отношения к моему конкретному вопросу, 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
. Тем не менее, хорошие решения для data.table
также довольно хороши (спасибо Жан-Роберту, Аруну, и обратите внимание, здесь я предпочел одно утверждение перед строго самым оптимальным решением):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
Синтаксис последнего может показаться очень эзотерическим, но на самом деле он довольно прост, если вы привыкли к data.table
(т.е. не используете некоторые из более эзотерических приемов).
В идеале, я хотел бы увидеть несколько хороших примеров, где dplyr
или data.table
значительно более лаконичны или 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
), в которыхdata.table
становится значительно быстрее. - @Arun провел несколько тестов для объединений, показав, что
data.table
масштабируется лучше, чемdplyr
с увеличением числа групп (обновлено сdplyr
последних улучшений в обоих пакетах и последней версии R). Кроме того, тест при попытке получить уникальные значения имеетdata.table
~ в 6 раз быстрее. - (Неподтвержденный) имеет
data.table
75% быстрее на больших версиях группы /apply/sort, в то время какdplyr
был на 40% быстрее на меньших ( еще один вопрос SO из комментариев, спасибо данам). - Мэтт, главный автор
data.table
, имеет протестированные группировка операций поdata.table
,dplyr
и питонаpandas
на срок до 2 миллиардов строк (~ 100GB в оперативной памяти). - В более старом тесте для групп из
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))