Relatório das Análises de Produção e Venda de Cervejas em Bangalore de 2020 a 2024

Autor
Afiliação

Miqueias Teixeira Silva, Bianca Lopes Lang, Lucas Magalhães Ast, Gabriel Cordeiro Chileider e Júlia Zorzo Ferreira.

Data de Publicação

18 de novembro de 2024

Resumo

Este relatório apresenta uma análise abrangente do dataset “Brewery Operations and Market Analysis Dataset”, o qual fornece dados de produção, qualidade e vendas de cervejas artesanais na cidade de Bangalore, Índia, no período de janeiro de 2020 a janeiro de 2024. Com o intuito de fomentar o interesse e o investimento de empresários no ramo de cervejarias artesanais, o estudo visa fornecer insights sobre esse mercado a partir de uma análise exploratória dos dados. Durante a análise foram investigadas, através de amostras e o uso de estatísticas descritivas, as correlações entre diferentes variáveis e as tendências de venda, além da visualização de gráficos que associam os dados. Como resultado, podemos compreender as correlações moderadas e fortes entre as variáveis, por exemplo, que o estilo da cerveja (Beer_Style) influencia no faturamento (Total_Sales), ou então a relação entre o Local de produção (Location) e o formato das cervejas (SKU).

Palavras-chave

Análise de Dados, Exemplo

Introdução

O conjunto de dados intitulado Brewery Operations and Market Analysis Dataset (Ankur, 2024) oferece dados detalhados sobre as operações de uma cervejaria entre os anos de 2020 e 2024, na cidade de Bangalore, Índia. Inicialmente, a base de dados conta com 22 variáveis e 10 milhões de observações. As variáveis presentes, em seus nomes originais, são:

  • Batch_ID - Um identificador único para cada lote de cerveja produzido;
  • Brew_Date - A data e horário em que a cerveja foi produzida;
  • Beer_Style - O tipo de cerveja produzida, por exemplo, Stout ou Ale;
  • SKU - O tipo de embalagem da cerveja produzida, por exemplo, garrafa ou lata;
  • Location - A localização em que a cerveja foi produzida, sendo ela um bairro de Bangalore;
  • Fermentation_Time - O tempo de fermentação da cerveja, medido em dias;
  • Temperature - A temperatura média da cerveja, em graus Celsius, mantida durante o processo de fermentação;
  • pH_level - O pH da cerveja produzida;
  • Gravity - Uma medida da densidade da cerveja em comparação com a água, indicando o teor alcoólico potencial;
  • Alcohol_Content - A porcentagem de álcool da cerveja em relação ao volume produzido no lote;
  • Bitterness - A amargura da cerveja, medida em Unidades Internacionais de Amargor (IBU);
  • Color - A cor da cerveja, medida usando o Método de Referência Padrão (SRM);
  • Ingredient_Ratio - A proporção de malte e lúpulo usada na produção da cerveja em relação à quantidade de água;
  • Volume_Produced - O volume de cerveja produzido no lote, medido em litros;
  • Total_Sales - O total de vendas geradas pelo lote, expresso em dólares americanos (USD);
  • Quality_Score - Uma pontuação geral de qualidade atribuída ao lote de cerveja, avaliada de 0 a 10;
  • Brewhouse_Efficiency - A eficiência do processo de produção, expressa como porcentagem;
  • Loss_During_Brewing - A porcentagem de perda de volume durante o processo de produção;
  • Loss_During_Fermentation - A porcentagem de perda de volume durante o processo de fermentação;
  • Loss_During_Bottling_Kegging - A porcentagem de perda de volume durante o processo de engarrafamento ou envasamento.

Além das variáveis apresentadas, a fim de realizar uma análise exploratória, foram adicionadas as variáveis a seguir:

  • Preço_litro - O preço por litro da cerveja, calculado a partir das variáveis Volume_Produced e Total_Sales;
  • Mes - Mês da produção do lote;
  • Ano - Ano da produção do lote;
  • Grain - Proporção/porcentagem de Malte em relação à quantidade de água;
  • Hop - Proporção/porcentagem de Lúpulo em relação à quantidade de água.

Na próxima seção serão apresentados mais detalhes a respeito do motivo dessas variáveis terem sido acrescentadas no banco. Além disso, serão discutidos os objetivos do estudo e a metodologia utilizada para a análise dos dados.

Materiais e Métodos

Após fazer o download da base de dados encontrada em (Ankur, 2024), foi realizada a leitura dos dados e a criação das novas variáveis já citadas. Para isso, foi utilizada a linguagem de programação R e pacotes como “data.table”, “tidyverse’,”magrittr”, como apresentado a seguir:

Código
# Função para carregar pacotes:
load_packages <- function(packages) {
  for (package in packages) {
    if (!require(package, character.only = TRUE, quietly = TRUE)) {
      cat(paste("Instalando pacote:", package, "\n"))
      install.packages(package, dependencies = TRUE)
      library(package, character.only = TRUE)
    }
  }
}

# Lista de pacotes necessários:
packages <- c(
  "tidyverse",
  "data.table",
  "magrittr",
  "corrplot",
  "shiny",
  "lubridate",
  "scales",
  "gridExtra",
  "modelr",
  "broom",
  "car",
  "ggpubr",
  "viridis",
  "knitr",
  "kableExtra"
)

# Carregamento dos pacotes:
load_packages(packages)

Para fazer a leitura dos dados, aplica-se o código a seguir:

Código
# dados <- fread("99_dados/brewery/brewery_data_complete_extended.csv")
dados <- fread("brewery_data_complete_extended.csv")
# Criar uma amostra aleatória de 100 mil linhas:
set.seed(123) # Fixar a semente para reprodutibilidade
dados <- dados[sample(.N, 100000)]

# Verificar a amostra
head(dados)
   Batch_ID           Brew_Date Beer_Style     SKU        Location
      <int>              <POSc>     <char>  <char>          <char>
1:  6342681 2021-04-22 13:55:43        Ale   Pints     Rajajinagar
2:  7824350 2021-02-10 13:20:48       Sour Bottles       Yelahanka
3:  3184606 2023-01-30 17:04:40       Sour   Pints     Indiranagar
4:  4798433 2022-05-10 18:46:50    Pilsner    Kegs       Jayanagar
5:  5928873 2021-11-16 10:01:46    Pilsner    Kegs     Malleswaram
6:  4643770 2020-02-28 21:53:51       Sour Bottles Electronic City
   Fermentation_Time Temperature pH_Level  Gravity Alcohol_Content Bitterness
               <int>       <num>    <num>    <num>           <num>      <int>
1:                19    18.27663 4.693490 1.054182        5.936416         30
2:                11    22.96749 5.257924 1.036089        5.493399         31
3:                13    21.20562 4.587301 1.069229        4.606987         46
4:                13    24.29844 4.506486 1.038526        5.332764         54
5:                19    16.23232 4.651979 1.048781        5.709051         33
6:                12    18.53211 5.338767 1.031514        5.340030         51
   Color Ingredient_Ratio Volume_Produced Total_Sales Quality_Score
   <int>           <char>           <int>       <num>         <num>
1:    16      1:0.39:0.11            1219    2402.660      6.421240
2:    13      1:0.38:0.20            3845   11213.558      6.912467
3:    19      1:0.26:0.18            2462   10882.890      7.571706
4:     8      1:0.35:0.19             781   19196.191      6.597743
5:    17      1:0.39:0.26             713    1616.202      6.197956
6:     5      1:0.44:0.21            3246    1317.590      6.537595
   Brewhouse_Efficiency Loss_During_Brewing Loss_During_Fermentation
                  <num>               <num>                    <num>
1:             85.22984            1.106138                 2.723314
2:             80.82567            4.376264                 2.931115
3:             70.18912            2.664189                 1.635399
4:             79.48404            4.676963                 1.799524
5:             77.18665            3.669859                 4.654746
6:             74.87334            2.532383                 3.950904
   Loss_During_Bottling_Kegging
                          <num>
1:                     3.684080
2:                     4.302363
3:                     1.150344
4:                     2.848651
5:                     3.505853
6:                     2.898631

A criação das novas variáveis foi realizada da seguinte forma:

  • A variável Preço_litro:
Código
dados <- dados %>%
  mutate(Preco_Litro = Total_Sales / Volume_Produced)
  • A variável Mes:
Código
dados$Mes <- month(dados$Brew_Date)
  • A variável Ano:
Código
dados$Ano <- year(dados$Brew_Date)
  • A criação das colunas Grain e Hop, razões da variável Ingredient_Ratio:
Código
dados[, c("water", "grain", "hop") := tstrsplit(Ingredient_Ratio, ":",
                                                type.convert = TRUE)
      ]  
dados$water <- NULL 
dados$grain <- dados$grain * 100     
dados$hop <- dados$hop * 100

Diante disso, a análise exploratória dos dados foi realizada conforme a próxima seção:

Análise Exploratória dos Dados

Análise Univariada

Em um primeiro momento, as variáveis foram analisadas individualmente, antes de ser buscada alguma correlação entre elas. Para tal, foi aplicado o código summary(dados).

O summary permite dar uma visão geral das variáveis quantitativas, apresentando média, mediana, mínimo, máximo e quartis. Por exemplo, a variável Brew_Date tem como mínimo o dia 1 de janeiro de 2020, correspondene ao dado do primeiro lote (Batch_ID), e o máximo o dia 31/12/2023, do última lote, isso com seus respectivos horários.

A variável Fermentation_Time possui valor mínimo de 12 dias, máximo de 19 dias e média de 14,5 dias.

Por sua vez, a variável Temperature tem média de 20,0 graus Celsius e seus mínimos e máximos correspondem a 15ºC e 25ºC, respectivamente. Já o pH_level tem média 4,5, e valores mínimo e máximo 4,0 e 5,0, respectivamente.

Outras variáveis quantitativas como Quality_Score, Alcohol_Content, BrewHouse_Efficiency, Loss_During_Brewing, Loss_During_Fermentation também foram analisadas e serão sintetizados na tabela abaixo os resultados encontrados.

Código
library(dplyr)
library(tidyr)

tabela_max_min_med <- dados %>%
  summarise(Quality_Score_max = max(Quality_Score),
            Quality_Score_min = min(Quality_Score),
            Quality_Score_media = mean(Quality_Score),
            Alcohol_Content_max = max(Alcohol_Content),
            Alcohol_Content_min = min(Alcohol_Content),
            Alcohol_Content_media = mean(Alcohol_Content),
            BrewHouse_Efficiency_max = max(Brewhouse_Efficiency),
            BrewHouse_Efficiency_min = min(Brewhouse_Efficiency),
            BrewHouse_Efficiency_media = mean(Brewhouse_Efficiency),
            Loss_During_Brewing_max = max(Loss_During_Brewing),
            Loss_During_Brewing_min = min(Loss_During_Brewing),
            Loss_During_Brewing_media = mean(Loss_During_Brewing),
            Loss_During_Fermentation_max = max(Loss_During_Fermentation),
            Loss_During_Fermentation_min = min(Loss_During_Fermentation),
            Loss_During_Fermentation_media = mean(Loss_During_Fermentation))

# Transformar a tabela para o formato desejado
tabela_trans <- tabela_max_min_med %>%
  pivot_longer(cols = everything(),
               names_to = c("variável", "estatística"),
               names_pattern = "(.*)_(.*)",
               values_to = "valor") %>%
  pivot_wider(names_from = estatística, values_from = valor)

# Exibir a tabela transformada
print(tabela_trans)
# A tibble: 5 × 4
  variável                   max   min media
  <chr>                    <dbl> <dbl> <dbl>
1 Quality_Score            10.0   6.00  8.00
2 Alcohol_Content           6.00  4.50  5.25
3 BrewHouse_Efficiency     90.0  70.0  80.0 
4 Loss_During_Brewing       5.00  1.00  2.99
5 Loss_During_Fermentation  5.00  1.00  3.00

Algo em comum em todas essas variáveis é que a média não muda, ou muda muito pouco (a diferença é na quarta casa decimal), independente do filtro que é aplicado. Por dizer, o tempo médio de fermentação (variável Fermentation_Time) ou a qualidade média (varíavel Quality_score) permanecem iguais ao agrupar por Ano, Mês, Location, Beer_Style, entre outros, sempre sendo algo muito próximo de 14,5 e 8, reespectivamente.

Agora que foi apresentada uma visão geral das variáveis quantitativas, serão analisadas as variáveis qualitativas.

  • A variável Beer_Style:

Ao aplicar o código unique(dados$Beer_Style), é possível encontrar os valores únicos da variável Beer_Style, que são: “Ale”, “IPA”, “Lager”, “Pilsner”, “Porter”, “Stout” e “Wheat”.

  • A variável Location:

Ao aplicar o código unique(dados$Location), é possível encontrar os valores únicos da variável Location, que são: “Whitefield”, “Malleswaram”, “Rajajinagar”, “Marathahalli”, “Electronic City” “Indiranagar”, “Koramangala”, “Yelahanka”, “Jayanagar” e “HSR Layout”, todos bairros da cidade de Bangalore na Índia.

  • A variável SKU: Ao aplicar o código unique(dados$SKU), é possível encontrar os valores únicos da variável SKU, que são: “Bottles”, “Cans”, “Kegs” e “Pints”.

Análise Bivariada e Multivaríada

Diante do que foi feito, é possível relacionar as variáveis quantitativas e qualitativas. Por exemplo, qual foi o tipo de cerveja (Beer_Style) mais produzido (Volume_Produced) neste período? Qual foi o bairro (Location) que mais faturou em vendas de cerveja (total_Sales)?

Para encontrar o tipo de cerveja mais produzido, foi utilizado o código a seguir:

Código
prod_por_tipo <- dados %>%
  group_by(Beer_Style) %>%
  summarise(Total_produzido = sum(Volume_Produced))

print(prod_por_tipo)
# A tibble: 8 × 2
  Beer_Style Total_produzido
  <chr>                <int>
1 Ale               34389728
2 IPA               34468134
3 Lager             34187701
4 Pilsner           34125373
5 Porter            34624525
6 Sour              34482673
7 Stout             34087103
8 Wheat Beer        34372647

E assim chega-se à conclusão que o tipo de cerveja mais produzido foi o “Ale”, com um total 3438491666 unidades.

Para encontrar o bairro que mais faturou em vendas de cerveja, foi utilizado o código a seguir:

Código
fat_por_local<- dados %>%
  group_by(Location) %>%
  summarise(Total_Sales = sum(Total_Sales)) %>%
  arrange(desc(Total_Sales))

E assim obtém-se a tabela:

Código
print(fat_por_local)
# A tibble: 10 × 2
   Location        Total_Sales
   <chr>                 <dbl>
 1 Rajajinagar      105616178.
 2 HSR Layout       105510662.
 3 Whitefield       105506628.
 4 Electronic City  105408189.
 5 Yelahanka        105399763.
 6 Malleswaram      104754305.
 7 Indiranagar      104692961.
 8 Jayanagar        104178186.
 9 Koramangala      103922248.
10 Marathahalli     102748332.

É possível relacionar outras variáveis, sendo uma delas qualitativa e a outra quantitativa, não sendo necessário desenvolver um código para cada variável. Para isso, foi criada uma função em que há inserção das variáveis desejadas e retorno de uma tabela com os resultados.

Código
func_quali_quant <- function(quali, quant){
  dados %>%
    group_by({{quali}}) %>%
    summarise(Total = sum({{quant}})) %>%
    arrange(desc(Total))
}

Por exemplo, supondo que o interesse está em saber o volume produzido de cerveja por ano, basta aplicar a função func_quali_quant com os argumentos Ano e Volume_Produced. Lembrando: a variável Ano é qualitativa.

Código
#Exibir a tabela
func_quali_quant(Ano, Volume_Produced)
# A tibble: 4 × 2
    Ano    Total
  <int>    <int>
1  2021 69198457
2  2020 68655199
3  2022 68498989
4  2023 68385239

E assim é gerada a tabela com o volume produzido de cerveja por ano. O ano que mais produziu cerveja foi 2020, enquanto que 2021 foi o ano de menor produção.

Para separar por meses, basta aplicar a função na variável Mes em vez de Ano.

Também é possível criar uma função que relacione duas variáveis, Mes e Ano. Supondo que é desejável saber o top 5 maiores faturamentos (Total_Sales) de cerveja separado por tipo (Beer_Style), em um mês ou ano específico, pode ser aplicada a seguinte função:

  • Para ano:
Código
func_qtde_vendida_ano <- function(ano){
  dados %>%
    filter(Ano == ano) %>%
    group_by(Beer_Style) %>%
    summarise(Total_vendido = sum(Total_Sales)) %>%
    arrange(desc(Total_vendido)) %>%
    head(5)
}
  • Para mês:
Código
func_qtde_vendida_mes <- function(mes){
  dados %>%
    filter(Mes == mes) %>%
    group_by(Beer_Style) %>%
    summarise(Total_vendido = sum(Total_Sales)) %>%
    arrange(desc(Total_vendido)) %>%
    head(5)
}

Como exemplo do uso, para aplicar a função no ano de 2020, basta rodar a linha de código func_qtde_vendida_ano(2020). Para o mês de Maio, basta rodar a linha de código func_qtde_vendida_mes(5).

Assim, é possível concluir que os tipos de cervejas que tiveram maior faturamento em 2020 foram Ale, Sour, Wheat Beer, Porter e Pilsner. Mais além, para o mês de maio correspondente aos 4 anos analisados, as cervejas que tiveram maior faturamento foram Ale, Lager, Porter, Pilsner e Sour.

É possível aplicar o mesmo raciocínio em outras variáveis, como Location ou SKU, além de criar gráficos de dispersão entre valor produzido e valor vendido, por Ano e Mes.

Código
library(tidyverse)
library(lubridate)

# Criando uma data completa combinando Ano e Mês
dados <- dados %>%
  mutate(data = make_date(year = Ano, month = Mes, day = 1))

# Criando a série temporal por Location
serie_temporal <- dados %>%
  group_by(Location, data) %>%
  summarise(Total_Sales = sum(Total_Sales)) %>%
  ungroup()

# Criando o gráfico com facet_wrap
ggplot(serie_temporal, aes(x = data, y = Total_Sales)) +
  geom_line(color = "blue") +
  geom_point(color = "blue") +
  facet_wrap(~Location, scales = "free_y", ncol = 2) +
  theme_minimal() +
  labs(title = "Vendas Totais por Localização",
       x = "Data",
       y = "Vendas Totais") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        strip.text = element_text(size = 10, face = "bold"),
        strip.background = element_rect(fill = "lightgray"))

Normalização dos Dados:

Por que usar o gráfico com dados normalizados?

O gráfico com normalização é uma abordagem útil quando queremos comparar variáveis que têm escalas e magnitudes muito diferentes, como no caso de Volume Produzido e Total de Vendas. Aqui está o motivo para utilizá-lo:


1. Escalas diferentes dificultam a comparação

  • No seu caso, o Volume Produzido e o Total de Vendas provavelmente têm valores muito diferentes em magnitude (por exemplo, milhares de unidades versus milhões em vendas).
  • Se os dois valores forem plotados no mesmo gráfico sem ajustes, o eixo Y será dominado pela variável com maior magnitude, tornando a outra quase invisível.
  • Exemplo do problema:
    • Se Volume Produzido varia de 100 a 10.000, mas Total de Vendas varia de 1.000.000 a 10.000.000, a curva do volume será achatada e difícil de interpretar.

A normalização resolve isso, trazendo ambas as variáveis para a mesma escala (de 0 a 1).


2. Identificar tendências e padrões relativos

  • A normalização permite observar padrões relativos para as duas variáveis.
    • Por exemplo: “O Volume Produzido e o Total de Vendas aumentam juntos ao longo dos meses?” ou “Há meses em que a produção aumenta, mas as vendas diminuem?”.
  • Com os dados na mesma escala, pode-se comparar diretamente a relação entre as variações, sem se preocupar com os valores absolutos.

3. Quando valores absolutos não são o foco

  • Se o objetivo da análise for entender a relação entre as variáveis (como elas variam em conjunto ao longo do tempo) e não os valores exatos, a normalização é a melhor abordagem.
  • Exemplo de pergunta respondida pelo gráfico normalizado:
    • “Quando o volume produzido aumenta, o total de vendas também aumenta proporcionalmente?”
    • “Existe um atraso entre o aumento da produção e o aumento das vendas?”

4. Claridade visual

  • Com os valores normalizados, ambos os conjuntos de dados ocupam a mesma faixa no gráfico (de 0 a 1), o que facilita a visualização de padrões e evita que um conjunto “esconda” o outro.
  • As linhas normalizadas mostram claramente como as variáveis se comportam em relação ao tempo (por exemplo, mês a mês).

Quando NÃO usar a normalização

  • Se os valores absolutos forem importantes para a análise.
    • Por exemplo, se o interesse é mostrar que o Total de Vendas é 100x maior que o Volume Produzido, a normalização não seria adequada, pois ela “esconde” as diferenças de magnitude.
    • Nesse caso, gráficos de barras ou eixos separados seriam mais apropriados.

Resumo

É utilizada a normalização quando:

  1. As variáveis têm escalas muito diferentes;
  2. O objetivo é comparar tendências e padrões relativos, e não valores absolutos;
  3. Há busca por clareza visual para observar como as variáveis se comportam em relação ao tempo ou outros fatores.

Outra forma de visualiação desse gráfico seria:

Observe que ele não transmite informações de relevância.

Código
# Reorganizar os dados no formato longo (long format) para o gráfico:
dados_long <- dados %>%
  pivot_longer(cols = c(Volume_Produced, Total_Sales), 
               names_to = "Indicador", 
               values_to = "Valor")

# Gráfico de barras lado a lado:
ggplot(data = dados_long, aes(x = Mes, y = Valor, fill = Indicador)) +
  geom_bar(stat = "identity", position = "dodge") + # Barras agrupadas
  facet_wrap(~ Ano, nrow = 2) + # Separar por ano
  labs(
    title = "Comparação: Volume Produzido vs Total de Vendas",
    x = "Mês",
    y = "Valores Absolutos",
    fill = "Indicador"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
    axis.text.x = element_text(size = 12),
    legend.position = "bottom"
  )

Uma outra visualização pode ser feita através de séries temporais de vendas totais ao longo do mês por ano:

Código
# Inserir os 4 gráficos de séries temporais de vendas totais ao longo do mês por ano:

# Criando uma data completa combinando Ano e Mês:
dados <- dados %>%
  mutate(data = make_date(year = Ano, month = Mes, day = 1))

# Criando a série temporal por Location
serie_temporal <- dados %>%
  group_by(Location, data) %>%
  summarise(Total_Sales = sum(Total_Sales)) %>%
  ungroup()

# Criando o gráfico com facet_wrap
ggplot(serie_temporal, aes(x = data, y = Total_Sales)) +
  geom_line(color = "blue") +
  geom_point(color = "blue") +
  facet_wrap(~Location, scales = "free_y", ncol = 2) +
  theme_minimal() +
  labs(title = "Serie Temporal de Vendas Totais por Localização",
       x = "Data",
       y = "Vendas Totais") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        strip.text = element_text(size = 10, face = "bold"),
        strip.background = element_rect(fill = "lightgray"))

Código
# Preparação dos dados:
dados <- dados %>%
  mutate(data = make_date(year = Ano, month = Mes, day = 1))

serie_temporal <- dados %>%
  group_by(Location, data) %>%
  summarise(Total_Sales = sum(Total_Sales)) %>%
  ungroup()

# 1. Gráfico das Séries Temporais:
plot_series <- ggplot(serie_temporal, aes(x = data, y = Total_Sales)) +
  geom_line(color = "blue") +
  geom_point(color = "blue") +
  facet_wrap(~Location, scales = "free_y", ncol = 2) +
  theme_minimal() +
  labs(title = "Serie Temporal de Vendas Totais por Localização",
       x = "Data",
       y = "Vendas Totais") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        strip.text = element_text(size = 10, face = "bold"),
        strip.background = element_rect(fill = "lightgray"))

print(plot_series)

Código
# 2. Resumo Estatístico:
resumo_locais <- serie_temporal %>%
  group_by(Location) %>%
  summarise(
    Total_Vendido = sum(Total_Sales),
    Media_Mensal = mean(Total_Sales),
    Desvio_Padrao = sd(Total_Sales),
    Min_Vendas = min(Total_Sales),
    Max_Vendas = max(Total_Sales),
    CV = (Desvio_Padrao/Media_Mensal)*100
  ) %>%
  arrange(desc(Total_Vendido))

print(kable(resumo_locais, caption = "Resumo Estatístico por Localização"))


Table: Resumo Estatístico por Localização

|Location        | Total_Vendido| Media_Mensal| Desvio_Padrao| Min_Vendas| Max_Vendas|        CV|
|:---------------|-------------:|------------:|-------------:|----------:|----------:|---------:|
|Rajajinagar     |     105616178|      2200337|      170539.6|    1854863|    2588592|  7.750613|
|HSR Layout      |     105510662|      2198139|      158604.0|    1878376|    2706323|  7.215375|
|Whitefield      |     105506628|      2198055|      158046.2|    1815695|    2483810|  7.190277|
|Electronic City |     105408189|      2196004|      170450.0|    1868617|    2621174|  7.761824|
|Yelahanka       |     105399763|      2195828|      190083.6|    1867227|    2633014|  8.656580|
|Malleswaram     |     104754305|      2182381|      166141.7|    1832547|    2666730|  7.612864|
|Indiranagar     |     104692961|      2181103|      221889.5|    1749752|    2754744| 10.173269|
|Jayanagar       |     104178186|      2170379|      164139.2|    1644112|    2606602|  7.562699|
|Koramangala     |     103922248|      2165047|      146125.0|    1834997|    2443758|  6.749275|
|Marathahalli    |     102748332|      2140590|      181450.4|    1774941|    2528238|  8.476655|
Código
# 3. Análise de Sazonalidade:
plot_sazonalidade <- serie_temporal %>%
  mutate(mes = factor(month(data),
                      levels = 1:12,
                      labels = c("Jan", "Fev", "Mar", "Abr", "Mai", "Jun",
                               "Jul", "Ago", "Set", "Out", "Nov", "Dez"))) %>%
  group_by(Location, mes) %>%
  summarise(media_vendas = mean(Total_Sales)) %>%
  ggplot(aes(x = mes, y = media_vendas, fill = Location)) +
  geom_bar(stat = "identity", position = "dodge") +
  theme_minimal() +
  labs(title = "Média de Vendas por Mês e Localização",
       x = "Mês",
       y = "Média de Vendas") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

print(plot_sazonalidade)

Código
# 4. Análise de Performance:
# Top 3:
top_3 <- serie_temporal %>%
  group_by(Location) %>%
  summarise(total = sum(Total_Sales)) %>%
  top_n(3, total) %>%
  arrange(desc(total))

# Bottom 3:
bottom_3 <- serie_temporal %>%
  group_by(Location) %>%
  summarise(total = sum(Total_Sales)) %>%
  top_n(-3, total) %>%
  arrange(total)

cat("\nTop 3 Localizações:\n")

Top 3 Localizações:
Código
print(kable(top_3))


|Location    |     total|
|:-----------|---------:|
|Rajajinagar | 105616178|
|HSR Layout  | 105510662|
|Whitefield  | 105506628|
Código
cat("\nBottom 3 Localizações:\n")

Bottom 3 Localizações:
Código
print(kable(bottom_3))


|Location     |     total|
|:------------|---------:|
|Marathahalli | 102748332|
|Koramangala  | 103922248|
|Jayanagar    | 104178186|
Código
# 5. Análise de Crescimento:
crescimento <- serie_temporal %>%
  group_by(Location) %>%
  arrange(data) %>%
  summarise(
    primeira_venda = first(Total_Sales),
    ultima_venda = last(Total_Sales),
    crescimento_perc = ((ultima_venda - primeira_venda) / primeira_venda) * 100,
    periodo_inicial = first(data),
    periodo_final = last(data)
  ) %>%
  arrange(desc(crescimento_perc))

print(kable(crescimento, caption = "Crescimento Percentual por Localização"))


Table: Crescimento Percentual por Localização

|Location        | primeira_venda| ultima_venda| crescimento_perc|periodo_inicial |periodo_final |
|:---------------|--------------:|------------:|----------------:|:---------------|:-------------|
|Marathahalli    |        1927909|      2430287|       26.0581472|2020-01-01      |2023-12-01    |
|Electronic City |        1958859|      2347401|       19.8351545|2020-01-01      |2023-12-01    |
|HSR Layout      |        1948927|      2271263|       16.5391496|2020-01-01      |2023-12-01    |
|Rajajinagar     |        1975578|      2144818|        8.5665891|2020-01-01      |2023-12-01    |
|Jayanagar       |        2121688|      2149044|        1.2893411|2020-01-01      |2023-12-01    |
|Indiranagar     |        2198369|      2189605|       -0.3986646|2020-01-01      |2023-12-01    |
|Malleswaram     |        2302602|      2198575|       -4.5178124|2020-01-01      |2023-12-01    |
|Whitefield      |        2315656|      2118368|       -8.5197337|2020-01-01      |2023-12-01    |
|Koramangala     |        2354625|      2053970|      -12.7686796|2020-01-01      |2023-12-01    |
|Yelahanka       |        2407072|      2076197|      -13.7459829|2020-01-01      |2023-12-01    |
Código
# 6. Gráfico de Crescimento:
plot_crescimento <- ggplot(crescimento, aes(x = reorder(Location, crescimento_perc), 
                                          y = crescimento_perc)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_flip() +
  theme_minimal() +
  labs(title = "Crescimento Percentual por Localização",
       x = "Localização",
       y = "Crescimento (%)")

print(plot_crescimento)

Código
# 7. Análise de Correlação:
matriz_vendas <- serie_temporal %>%
  pivot_wider(names_from = Location, 
              values_from = Total_Sales) %>%
  select(-data)

correlacao <- cor(matriz_vendas, use = "pairwise.complete.obs")

corrplot(correlacao, 
         method = "color",
         type = "upper",
         tl.col = "black",
         tl.srt = 45,
         addCoef.col = "black")

Código
# 8. Insights Principais:
cat("\nInsights Principais:\n")

Insights Principais:
Código
cat("\nDesempenho Geral:")

Desempenho Geral:
Código
cat("\n- Top 3 localizações:", paste(top_3$Location, collapse = ", "))

- Top 3 localizações: Rajajinagar, HSR Layout, Whitefield
Código
cat("\n- Bottom 3 localizações:", paste(bottom_3$Location, collapse = ", "))

- Bottom 3 localizações: Marathahalli, Koramangala, Jayanagar
Código
cat("\n- Localização com maior crescimento:", 
    crescimento$Location[1], 
    "com", 
    round(crescimento$crescimento_perc[1], 2), 
    "%")

- Localização com maior crescimento: Marathahalli com 26.06 %
Código
# Salvando resultados.
# É possível adicionar comandos ggsave() para salvar os gráficos e write.csv() para salvar as tabelas de dados.

Além de gráfico da variação do preço por litro em relação a ano e mês:

Código
#Inserir o gráfico de variação do preço por litro em relação a Ano e Mes.
# Criando a coluna preco_litro:
dados <- dados %>%
  mutate(preco_litro = Total_Sales / Volume_Produced)

# Agora criando o gráfico:
ggplot(dados, aes(x = data, y = preco_litro)) +
  geom_line(color = "blue") +
  geom_point(color = "blue", size = 2) +
  theme_minimal() +
  labs(title = "Variação do Preço por Litro ao Longo do Tempo",
       x = "Data",
       y = "Preço por Litro (R$/L)") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_y_continuous(labels = scales::number_format(decimal.mark = ",",
                                                  big.mark = "."))

Código
# Versão com média mensal:
preco_medio_mensal <- dados %>%
  group_by(data) %>%
  summarise(preco_medio = mean(preco_litro)) %>%
  ungroup()

ggplot(preco_medio_mensal, aes(x = data, y = preco_medio)) +
  geom_line(color = "blue", size = 1) +
  geom_point(color = "blue", size = 2) +
  geom_smooth(method = "lm", color = "red", se = FALSE) +
  theme_minimal() +
  labs(title = "Variação do Preço Médio por Litro ao Longo do Tempo",
       x = "Data",
       y = "Preço Médio por Litro (R$/L)",
       subtitle = "Com linha de tendência") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_y_continuous(labels = scales::number_format(decimal.mark = ",",
                                                  big.mark = "."))

Código
# Calculando estatísticas importantes:
resumo_preco <- dados %>%
  summarise(
    preco_medio_geral = mean(preco_litro),
    preco_minimo = min(preco_litro),
    preco_maximo = max(preco_litro),
    desvio_padrao = sd(preco_litro),
    cv = (desvio_padrao/preco_medio_geral)*100
  )

# Calculando variação percentual total:
primeiro_preco <- dados %>% 
  arrange(data) %>% 
  slice(1) %>% 
  pull(preco_litro)

ultimo_preco <- dados %>% 
  arrange(data) %>% 
  slice(n()) %>% 
  pull(preco_litro)

variacao_total <- ((ultimo_preco - primeiro_preco)/primeiro_preco)*100

# Gráfico de tendência:
ggplot(dados, aes(x = data, y = preco_litro)) +
  geom_line(color = "blue") +
  geom_smooth(method = "lm", color = "red") +
  theme_minimal() +
  labs(title = "Tendência do Preço por Litro",
       x = "Data",
       y = "Preço (R$/L)") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Anormalidade nas médias das variáveis quantitativas

Após analisar as variáveis qualitativas, buscamos entender se as médias das variáveis quantitativas são influenciadas por alguma variável. Por exemplo, a qualidade média da cerveja aumenta ou diminui com a variação do formato da cerveja SKU? Ou então, o tempo médio de fermentação é influenciado pelo tipo de cerveja Beer_Style?

Para responder essas questões, foi criada uma função em que se insere uma variável qualitativa que servirá de filtro, uma variável quantitativa que será a variável analisada, e a média, o retono da função. Ela é dada por:

Código
func_media_quali_quant <- function(quali, quant){
  dados %>%
    group_by({{quali}}) %>%
    summarise(Media = mean({{quant}})) %>%
    arrange(desc(Media))
}

Por exemplo, para analisar qualidade média da cerveja por formato, basta aplicar a função: func_media_quali_quant com os argumentos SKU e Quality_Score.

Código
func_media_quali_quant(SKU, Quality_Score)
# A tibble: 4 × 2
  SKU     Media
  <chr>   <dbl>
1 Pints    8.01
2 Cans     8.01
3 Kegs     8.00
4 Bottles  8.00

Note que a qualidade média varia muito pouco entre os formatos de cerveja, sendo a média 8,0 para todos os formatos. Isso ocorre com qualquer outro filtro, por exemplo, ao analisar a qualidade média da cerveja pelo tipo de cerveja, temos:

Código
func_media_quali_quant(Beer_Style, Quality_Score)
# A tibble: 8 × 2
  Beer_Style Media
  <chr>      <dbl>
1 IPA         8.02
2 Pilsner     8.01
3 Sour        8.01
4 Lager       8.00
5 Wheat Beer  8.00
6 Porter      8.00
7 Ale         8.00
8 Stout       7.99

A média continua sendo 8,0, independentemente do tipo da cerveja.

O que foi feito acima pode ser feito com qualquer uma das variáveis quantitativas, sendo que a média permanece constante ou pouco varia, seja qual for o filtro.

Essa constatação é válida também para as correlações realizadas entre as variáveis quantitativas do banco de dados. Para realizar o cálculo dessas correlações, foram calculados os coeficientes de correlação de Pearson e utilizadas outras técnicas, as quais todas levaram a mesma conclusão acerca das médias, a de que elas são todas uniformes, independentemente dos filtros.

Tendo isso em vista, é importante afirmar que, de acordo com o proprietário da base de dados, que está disponível no Kaggle, os dados são puramente fictícios, o que explica a falta de correlação entre cor da cerveja e temperatura, por exemplo, variáveis que, na produção de cervejas reais, se relacionam. E o mesmo se aplica à interpretação das médias.

Conclusão

Além das citadas, foram realizadas outras análises a fim de compreender as relações entre as variáveis, apesar da ausência de correlações significativas e outros indicadores sem significância. Foi possível realizar a análise das vendas, processo produtivo, características da cerveja, entre outros, para que fosse possível concluir, por exemplo, que a maioria dos lotes produzidos foram de fato vendidos, que as perdas durante a fermentação e envasamento foram mínimas e que, de acordo com o tipo da cerveja, as cores correspondentes são bem similares entre diferentes bairros de Bangalore. Além, claro, do que foi anteriormente citado.

Referências