Visão geral
Estou relativamente familiarizado data.table
, não muito dplyr
. Eu li algumas dplyr
vinhetas e exemplos que apareceram no SO, e até agora minhas conclusões são as seguintes:
data.table
edplyr
são comparáveis em velocidade, exceto quando existem muitos grupos (ou seja,> 10-100K) e em outras circunstâncias (consulte os benchmarks abaixo)dplyr
tem sintaxe mais acessíveldplyr
abstrai (ou irá) possíveis interações com o banco de dados- Existem algumas pequenas diferenças de funcionalidade (consulte "Exemplos / uso" abaixo)
Na minha opinião, 2. não tem muito peso porque estou bastante familiarizado com isso data.table
, apesar de entender que, para os novos usuários de ambos, será um grande fator. Eu gostaria de evitar uma discussão sobre o que é mais intuitivo, pois isso é irrelevante para minha pergunta específica feita da perspectiva de alguém já familiarizado data.table
. Também gostaria de evitar uma discussão sobre como "mais intuitivo" leva a análises mais rápidas (certamente verdade, mas, novamente, não é o que mais me interessa aqui).
Questão
O que eu quero saber é:
- Existem tarefas analíticas muito mais fáceis de codificar com um ou outro pacote para pessoas familiarizadas com os pacotes (ou seja, alguma combinação de pressionamentos de tecla exigida versus nível de esoterismo exigido, em que menos de cada uma é uma coisa boa).
- Existem tarefas analíticas executadas substancialmente (ou seja, mais de 2x) com mais eficiência em um pacote versus outro.
Uma recente pergunta do SO me fez pensar um pouco mais sobre isso, porque até aquele momento eu não pensava dplyr
em oferecer muito além do que já posso fazer data.table
. Aqui está a dplyr
solução (dados no final de Q):
dat %.%
group_by(name, job) %.%
filter(job != "Boss" | year == min(year)) %.%
mutate(cumu_job2 = cumsum(job2))
O que foi muito melhor do que minha tentativa de hackear uma data.table
solução. Dito isto, boas data.table
soluções também são muito boas (obrigado Jean-Robert, Arun, e observe que eu favoreci a declaração única sobre a solução estritamente mais ideal):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
A sintaxe para o último pode parecer muito esotérica, mas na verdade é bastante direta se você está acostumado data.table
(ou seja, não usa alguns dos truques mais esotéricos).
Idealmente, o que eu gostaria de ver são alguns bons exemplos, se a maneira dplyr
ou data.table
for substancialmente mais concisa ou tiver um desempenho substancialmente melhor.
Exemplos
Usodplyr
não permite operações agrupadas que retornam número arbitrário de linhas ( da pergunta de eddi , observe: isso parece que será implementado no dplyr 0.5 , também, @beginneR mostra uma possíveldo
solução alternativa usando a resposta à pergunta de @ eddi).data.table
suporta junções rolantes (obrigado @dholstius), bem como junções de sobreposiçãodata.table
otimiza internamente expressões do formulárioDT[col == value]
ouDT[col %in% values]
para velocidade por meio de indexação automática que usa pesquisa binária enquanto usa a mesma sintaxe R básica. Veja aqui para mais alguns detalhes e uma pequena referência.dplyr
oferece versões de avaliação padrão de funções (por exemploregroup
,summarize_each_
) que podem simplificar o uso programático dedplyr
(note que o uso programático dedata.table
é definitivamente possível, requer apenas uma reflexão cuidadosa, substituição / citação, etc., pelo menos que eu saiba)
- Fiz meus próprios benchmarks e achei os dois pacotes comparáveis na análise de estilo "split apply combine", exceto quando há um número muito grande de grupos (> 100K), quando o ponto
data.table
se torna substancialmente mais rápido. - @Arun correu alguns benchmarks em junções , mostrando que as
data.table
escalas são melhores do quedplyr
quando o número de grupos aumenta (atualizado com aprimoramentos recentes nos pacotes e na versão recente do R). Além disso, uma referência ao tentar obter valores exclusivos temdata.table
~ 6x mais rápido. - (Não verificado) tem
data.table
75% mais rápido em versões maiores de um grupo / aplicar / classificar, enquantodplyr
foi 40% mais rápido em versões menores ( outra questão SO dos comentários , obrigado danas). - Matt, o principal autor de
data.table
, tenha aferido operações agrupamento emdata.table
,dplyr
e pythonpandas
em até 2 bilhões de linhas (~ 100GB de RAM) . - A referência mais antiga em grupos de 80K tem
data.table
~ 8x mais rápido
Dados
Este é o primeiro exemplo que mostrei na seção de perguntas.
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
e data.table
equipes estão trabalhando em benchmarks, portanto, uma resposta vai estar lá em algum ponto. # 2 (sintaxe) imO é estritamente falso, mas isso claramente se aventura no território das opiniões, por isso estou votando para fechar também.
(d)plyr
tem medida 0
dplyr
e plyr
com relação à sintaxe, e é basicamente a principal razão pela qual eu não gosto da sintaxe deles, é que eu tenho que aprender muitas funções extras (leia mais de 1) (com nomes que ainda não faz sentido para mim), lembre-se do que eles fazem, que argumentos eles tomam etc. Isso sempre foi uma grande desvantagem para mim da filosofia da plyr.
.SD
). [sério] Eu acho que essas são diferenças legítimas de design que irão agradar a pessoas diferentes
dplyr
um é:as.data.table(dat)[, .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], by = list(name, job)]