O Que É o dplyr
O dplyr é o pacote mais popular do R para manipulação de dados - uma "gramática de dados" construída a partir de um punhado de verbos. Cada verbo é uma função que recebe um data frame, faz exatamente um trabalho (manter algumas linhas, adicionar uma coluna, calcular um resumo por grupo) e retorna um novo data frame. Como todo verbo tem o mesmo formato - entra um data frame, sai um data frame - eles se encaixam com o pipe em pipelines que se leem de cima para baixo como uma receita. O dplyr é o núcleo do tidyverse, uma família de pacotes (tidyr, ggplot2, readr) que compartilha esse design.
Tudo o que o dplyr faz, o R base também faz. Aqui está uma pequena análise em R base puro - filtrar os dados embutidos de mtcars para carros de 6 cilindros, calcular uma nova coluna e tirar a média por número de marchas. Este exemplo é executável:
Funciona, e é bom R. Mas repare como a história fica espalhada entre indexação por colchetes, uma atribuição com $ e uma fórmula. A versão dplyr da mesma análise:
library(dplyr)
mtcars |>
filter(cyl == 4) |>
mutate(kml = mpg * 0.425) |>
group_by(gear) |>
summarize(avg_kml = round(mean(kml), 1))
Quatro verbos, na ordem em que você os explicaria em voz alta. Essa legibilidade é todo o argumento de venda, e em um pipeline de vinte etapas ela é decisiva.
Os trechos de dplyr desta página são estáticos porque este editor executa apenas R base - para rodá-los, instale o dplyr na sua própria máquina como mostrado a seguir.
Instalar e Carregar
Instalação única, depois carregue-o em todo script que o utiliza:
install.packages("dplyr") # once, per machine
library(dplyr) # every script
Instalar install.packages("tidyverse") em vez disso traz o dplyr mais seus irmãos. Quando o dplyr é carregado, ele avisa que mascara stats::filter e stats::lag - isso é normal, não um erro.
Os Seis Verbos Principais
Todo verbo recebe o data frame como seu primeiro argumento e os nomes de colunas sem aspas e sem prefixos df$.
filter() mantém as linhas que correspondem a uma condição:
mtcars |> filter(mpg > 25)
mtcars |> filter(cyl == 4, hp < 70) # comma = AND
select() mantém colunas por nome, intervalo ou função auxiliar:
mtcars |> select(mpg, cyl, hp)
mtcars |> select(mpg:hp) # a range of adjacent columns
mtcars |> select(starts_with("d")) # disp, drat
mutate() adiciona ou transforma colunas:
mtcars |> mutate(kml = mpg * 0.425, heavy = wt > 3.5)
arrange() ordena as linhas - envolva uma coluna em desc() para ordem decrescente:
mtcars |> arrange(desc(mpg))
summarize() colapsa as linhas em uma única linha de resumo, e group_by() faz com que o colapso aconteça por grupo:
mtcars |>
group_by(cyl) |>
summarize(n = n(), avg_mpg = mean(mpg))
group_by() não faz nada visível sozinho - ele apenas marca o data frame para que o próximo summarize() (ou mutate()) trabalhe grupo por grupo. Cada verbo tem uma documentação completa neste capítulo: filtrar linhas, adicionar colunas, ordenação e resumos por grupo.
Encadeando Verbos com o Pipe
O pipe |> pega o valor antes dele e o passa como primeiro argumento da função depois dele - x |> f(y) significa f(x, y). Como todo verbo do dplyr recebe e retorna um data frame, os verbos se encadeiam indefinidamente:
mtcars |>
filter(hp > 100) |>
mutate(kml = mpg * 0.425) |>
group_by(cyl) |>
summarize(cars = n(), avg_kml = round(mean(kml), 1)) |>
arrange(desc(avg_kml))
Leia em voz alta: pegue mtcars, mantenha os carros com mais de 100 cavalos, adicione uma coluna de km por litro, agrupe por cilindros, conte e tire a média de cada grupo, ordene pela média. Sem variáveis intermediárias, sem aninhamento. Código mais antigo usa %>% do pacote magrittr em vez de |> - para trabalho com dplyr eles são intercambiáveis, e o |> (embutido no R 4.1+) é coberto na documentação de pipes.
count() e n(): Os Auxiliares de Contagem
Contar é tão comum que o dplyr tem atalhos. n() retorna o número de linhas do grupo atual (válido apenas dentro de summarize() ou mutate()), e count() condensa toda a dança de group_by() + summarize(n = n()) em uma única chamada:
mtcars |> count(cyl) # rows per cyl value
mtcars |> count(cyl, gear, sort = TRUE) # two groupers, biggest first
Se você se pegar escrevendo group_by(x) |> summarize(n = n()), substitua por count(x).
Uma Nota Sobre Tibbles
Os verbos do dplyr costumam retornar um tibble - a variante do tidyverse de um data frame. Ele é um data frame (tudo que aceita um data frame aceita um tibble), com impressão mais amigável: apenas as 10 primeiras linhas, apenas as colunas que cabem, com os tipos exibidos sob cada nome. Duas diferenças que valem a pena conhecer: tibbles nunca usam nomes de linhas (é por isso que mtcars |> as_tibble() perde os nomes dos carros - o tidyverse espera que identificadores morem em uma coluna de verdade), e a indexação com colchete simples sempre retorna um tibble em vez de às vezes reduzir a um vetor. Nenhuma das duas deve surpreendê-lo no dia a dia; apenas não entre em pânico quando str() disser tbl_df.
O Que Você Leva Daqui
- O dplyr é uma gramática: seis verbos, cada um fazendo um trabalho com um data frame, encadeados com o pipe.
filter()escolhe linhas,select()escolhe colunas,mutate()adiciona colunas,arrange()ordena,group_by() + summarize()agrega.x |> f(y)éf(x, y)- pipelines se leem de cima para baixo, na ordem em que as coisas acontecem.count()en()cobrem a maioria das necessidades de contagem.- O R base consegue fazer tudo isso; o dplyr ganha em legibilidade quando os pipelines crescem.
A seguir: filtragem e subconjuntos em profundidade - os idiomas de colchetes do R base e onde o filter() do dplyr se encaixa.
Perguntas frequentes
O que é o dplyr no R?
O dplyr é o pacote de R mais usado para manipular data frames. Ele oferece um pequeno conjunto de verbos - filter(), select(), mutate(), arrange(), summarize(), group_by() - em que cada um faz uma única coisa com um data frame e se encadeia com o pipe em pipelines legíveis. Ele faz parte do tidyverse.
Como instalo o dplyr?
Execute install.packages("dplyr") uma vez e depois library(dplyr) no início de cada script que o utiliza. Instalar tidyverse em vez disso traz o dplyr mais seus pacotes irmãos (tidyr, ggplot2, readr) de uma só vez.
Eu preciso do dplyr, ou o R base é suficiente?
O R base consegue fazer tudo o que o dplyr faz - subconjuntos, aggregate(), order() - e vale a pena conhecê-lo porque funciona em qualquer lugar, sem dependências. O dplyr justifica sua instalação quando os pipelines ficam longos: cinco verbos encadeados se leem como uma frase, enquanto o equivalente em R base se lê como um quebra-cabeça de colchetes aninhados.
Qual é a diferença entre summarize e summarise no dplyr?
Nenhuma. São a mesma função com as grafias americana e britânica; o dplyr exporta as duas. Use a que seu time usa e seja consistente.