Menu

Agrupar e Resumir Dados no R (aggregate, tapply, dplyr)

Todas as formas de calcular estatísticas por grupo no R: contagem com table(), tapply() para uma estatística por grupo, a interface de fórmula do aggregate() e o group_by() com summarize() do dplyr.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Contando Linhas por Grupo: table()

A pergunta de agrupamento mais simples é "quantos de cada?" - e o R base responde em uma única chamada. table() conta quantas vezes cada valor aparece:

Uma coluna dá as contagens por valor; duas colunas dão uma tabulação cruzada completa (regiões nas linhas, planos nas colunas). Para "qual proporção?", envolva em prop.table(table(...)). table() é o caminho mais rápido para uma resposta de frequência em todo o R - não recorra a nada mais pesado quando tudo que você precisa é de uma contagem.

Uma Estatística por Grupo: tapply()

tapply(values, groups, function) divide o primeiro vetor pelo segundo e aplica a função a cada pedaço:

O resultado é um vetor nomeado - rótulos dos grupos como nomes, estatísticas como valores - o que o torna perfeito para consultas rápidas (means["EU"]). O nome vem de "table apply": aplicar uma função ao longo de uma tabela de agrupamento. Ele pertence à mesma família de sapply() e lapply(), tratadas no doc da família apply.

O limite do tapply() é o formato: um vetor nomeado é desajeitado para fazer merge, plotar ou continuar processando. Quando o resumo é um degrau intermediário e não a resposta final, você quer um data frame de volta - que é exatamente o que a próxima ferramenta retorna.

O Cavalo de Batalha das Fórmulas: aggregate()

aggregate() é o group-by completo do R base: ele retorna um data frame, e sua interface de fórmula se lê como a frase que você diria. value ~ group significa "value, desagregado por group":

Adicionar agrupadores é só acrescentar + outra_coluna na fórmula - a segunda chamada soma por combinação de região e trimestre. Você também pode agregar várias colunas de valores de uma vez com cbind(a, b) ~ group. Como a saída é um data frame comum, ela se encaixa direto em um merge, uma ordenação ou um gráfico - esta é a ferramenta base padrão para resumos agrupados.

Um comportamento discreto que vale conhecer: a interface de fórmula descarta linhas com NA em qualquer coluna usada antes de agregar. Geralmente é o que você quer; ocasionalmente é a explicação para uma contagem que parece baixa.

O Jeito dplyr: group_by() + summarize()

O padrão moderno é o par de verbos do dplyr - group_by() declara o agrupamento, summarize() colapsa cada grupo em uma linha, calculando quantas estatísticas você nomear (estático; o sandbox roda apenas R base):

library(dplyr)

sales |>
    group_by(region) |>
    summarize(
        n     = n(),
        total = sum(amount),
        avg   = mean(amount)
    )

É aqui que o dplyr realmente supera o R base: várias estatísticas por grupo em uma chamada legível - aggregate() precisa de contorcionismos para isso - além de n() de graça, e o resultado flui direto para o próximo pipe. (summarise() é a mesma função, com grafia britânica.)

Uma coisa que confunde iniciantes: com vários agrupadores, summarize() remove apenas o último, deixando o resultado ainda agrupado - e imprime uma mensagem avisando. Diga explicitamente o que você quer com o argumento .groups: summarize(avg = mean(amount), .groups = "drop") retorna um data frame simples e desagrupado, que é o hábito padrão correto. Um data frame agrupado que escapa para o código posterior faz mutate() e companhia operarem silenciosamente por grupo - uma fonte clássica de resultados confusos.

Escolhendo Entre Elas

  • Uma contagem - table(), nada supera uma chamada só.
  • Uma estatística, olhada rápida - tapply(), e leia a resposta direto do vetor nomeado.
  • Data frame na saída, ambiente só com R base - aggregate() com uma fórmula.
  • Várias estatísticas, parte de um pipeline, ou qualquer coisa ambiciosa - group_by() |> summarize().

Não há resposta errada entre elas - todas calculam os mesmos números - mas combinar a ferramenta com o formato de saída de que você precisa poupa a etapa de conversão depois. Médias, medianas e medidas de dispersão em si são tratadas em estatística descritiva.

Exemplo Prático: mtcars por Número de Cilindros

Tudo junto em um dataset embutido - por número de cilindros, quantos carros existem e qual a média de consumo e potência:

Onze carros de 4 cilindros com média de cerca de 26,7 mpg, sete de 6 cilindros em torno de 19,7, quatorze de 8 cilindros em torno de 15,1 - e a potência marchando na direção oposta. Duas chamadas, uma tabela-resumo completa: é para responder esse tipo de pergunta que a agregação por grupos existe.

O Que Você Leva

  • table() para contagens, prop.table() para proporções.
  • tapply(values, groups, fn) retorna um vetor nomeado - olhadas rápidas, consultas fáceis.
  • aggregate(value ~ group, data, FUN) retorna um data frame; + adiciona agrupadores, cbind() adiciona colunas de valores.
  • O group_by() |> summarize(n = n(), avg = mean(x), .groups = "drop") do dplyr é o padrão moderno para resumos com várias estatísticas.
  • Escolha pelo formato de saída; todas concordam nos números.

A seguir: combinando tabelas que compartilham uma chave - merge() e a família de joins do dplyr.

Perguntas frequentes

Como calculo a média por grupo no R?

O R base tem duas ferramentas: tapply(df$value, df$group, mean) retorna um vetor nomeado com as médias de cada grupo, e aggregate(value ~ group, data = df, FUN = mean) retorna o mesmo resultado como data frame. No dplyr: df |> group_by(group) |> summarize(avg = mean(value)).

Como conto ocorrências por grupo no R?

table(df$group) conta as linhas por valor do grupo em uma única chamada; table(df$a, df$b) faz a tabulação cruzada de duas colunas. No dplyr, count(df, group) faz o mesmo e retorna um data frame, o que facilita continuar o processamento.

O que a função aggregate() faz no R?

aggregate() divide um data frame por uma ou mais colunas de agrupamento, aplica uma função a cada pedaço e retorna um data frame com os resultados. A interface de fórmula se lê naturalmente: aggregate(sales ~ region + quarter, data = df, FUN = mean) significa vendas, agrupadas por região e trimestre, com a média calculada.

Qual é a diferença entre tapply e aggregate?

Mesmo cálculo, formato de saída diferente. tapply() retorna um vetor nomeado (ou um array quando há dois agrupadores) - prático para consultas rápidas. aggregate() retorna um data frame - melhor quando o resultado alimenta uma análise posterior, um merge ou um gráfico. Na dúvida, aggregate().

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR