Mestrado Profissional em Administração
IFMG - Campus Formiga
15 de maio de 2025
O que vimos até aqui?
Aula 1 ✅
Aula 2 ✅
Aula 3 ✅
Aula 4 ✅
Conceitos de Variáveis e Observações em Estatística ✅
Conceito de Dados Organizados (Tidy Data) ✅
Tipos atômicos e classes principais de dados da linguagem R ✅
Tipos de Dados Tradicionais em Finanças: ✅
Importação e Preparação de Dados Típicos de Finanças com exemplos práticos ✅
Aula 5 ✅
Tópicos Vistos
Tópicos Planejados
Introdução ao Pacote dplyr
Pacote dplyr: Tipos Básicos de joins
Diretrizes para Aulas Mais Produtivas
⌨️ Código com método:
95% dos erros são evitáveis com:
🤝 Inteligência colaborativa:
💪 Capacidade de Resolver Problemas
Cada erro resolvido é uma evolução da sua habilidade analítica
Criando e transformando variáveis
A função mutate()
permite criar novas variáveis ou modificar variáveis existentes
Enquanto filter()
seleciona linhas e select()
seleciona colunas, mutate()
adiciona ou modifica colunas
É como ter uma “calculadora” que cria novas informações a partir dos dados existentes
Ideal para cálculos como: percentuais, totais, médias, categorias, etc.
Cria novas variáveis a partir das variáveis existentes
Como usar mutate() na prática
O que cada parte significa:
Cenário: Relatório de análise comercial
Imagine que a data frame gapminder
contém dados de vendas globais da sua empresa:
# Criando variáveis para análise de vendas
vendas_analise <- gapminder %>%
filter(year == 2007) %>% # Filtra dados somente de 2007
mutate(
# PIB total representa a receita total da região
receita_total = gdpPercap * pop,
# Receita em milhões (para facilitar a leitura)
receita_milhoes = receita_total / 1000000,
# Indicador de destaque (regiões com alta receita por pessoa)
destaque = gdpPercap > 20000
) %>%
# Vamos visualizar apenas algumas colunas e 5 linhas
select(country, receita_milhoes, gdpPercap, destaque) %>%
head(5)
vendas_analise
Interpretação administrativa: Este tipo de transformação é usado diariamente nas empresas para converter dados brutos em métricas de negócios úteis para tomada de decisão.
Transformações mais comuns: Operações aritméticas básicas
# Operações aritméticas básicas com mutate()
gapminder %>%
filter(country == "Brazil", year >= 2000) %>%
mutate(
# Adição: adiciona um valor fixo
pop_ajustada = pop + 1000000,
# Multiplicação: multiplica por um fator
gdp_reais = gdpPercap * 5.2, # Convertendo para reais
# Divisão: divide para mudar a escala
pop_milhoes = pop / 1000000 # População em milhões
) %>%
select(year, pop, pop_ajustada, pop_milhoes, gdpPercap, gdp_reais)
Dica: As operações mais utilizadas em análises de negócios são multiplicação (para fatores, taxas, conversões) e divisão (para mudar escalas e calcular proporções).
O que é a função ifelse()?
A função ifelse()
permite criar novas variáveis categóricas baseadas em condições:
Como funciona: ifelse(condição, valor_se_verdadeiro, valor_se_falso)
Criando KPIs com mutate() e ifelse()
gapminder %>%
filter(year == 2007) %>%
mutate(
pib_total = gdpPercap * pop, # PIB total
pib_percentual_global = (pib_total/sum(pib_total))*100, # % do PIB global
performance = ifelse(gdpPercap > mean(gdpPercap),
"Acima da média",
"Abaixo da média")
) %>%
select(country, pib_total, pib_percentual_global, performance)
Isso mostra como transformar dados brutos em informações gerenciais.
Quando precisamos de mais de duas categorias
case_when()
é como um “sistema de classificação” para criar categorias mais complexas:
# Exemplo de múltiplas categorias
paises_classificados <- gapminder %>%
filter(year == 2007) %>%
mutate(
classe_desenvolvimento = case_when(
gdpPercap < 2000 ~ "Baixo",
gdpPercap < 10000 ~ "Médio",
gdpPercap >= 10000 ~ "Alto"
)
) %>%
select(country, gdpPercap, classe_desenvolvimento) %>%
head(6)
paises_classificados
Como funciona:
condição ~ "valor a atribuir"
Escolhendo a função adequada
Função | Quando usar | Exemplo |
---|---|---|
ifelse() |
Para divisões simples em duas categorias | ifelse(vendas > meta, "Meta atingida", "Meta não atingida") |
case_when() |
Para múltiplas categorias ou condições complexas | Classificar clientes em “Bronze”, “Prata”, “Ouro” e “Platina” baseado em diferentes critérios |
Analogia de negócios:
ifelse()
é como uma decisão “sim/não” (aprovação de crédito simples)
case_when()
é como um sistema de classificação de clientes com várias categorias
Os erros que todos cometem no início
Usar o operador de atribuição errado
mutate(nova_var <- expressão)
❌mutate(nova_var = expressão)
✅Esquecer de salvar o resultado
dados %>% mutate(nova_var = x * 2)
❌ (resultado não salvo)dados_novos <- dados %>% mutate(nova_var = x * 2)
✅Tentar usar variáveis que acabou de criar sem manter os resultados
ERRADO:
CORRETO (Pipeline único):
O que você precisa lembrar
O que faz: mutate()
cria novas variáveis ou modifica existentes
Usos comuns no mundo dos negócios:
Como usar na prática:
Ferramentas complementares:
ifelse()
para classificações simples (sim/não)case_when()
para classificações múltiplasLembre-se de salvar o resultado em um novo objeto:
Exercícios Práticos
Nível 1: Começando com mutate()
Nível 2: Aplicando categorias
Usando ifelse()
, crie uma variável chamada economia_grande
que seja “Sim” quando a população for maior que 50 milhões e “Não” caso contrário.
Desafio: Usando dados de 2007, crie uma variável que classifique os países em três categorias baseadas na expectativa de vida:
Dica: Não se preocupe se não conseguir resolver todos. Foque em entender a lógica!
Agrupando e resumindo dados
A função group_by()
permite agrupar dados por uma ou mais variáveis categóricas
A função summarize()
(ou summarise()
) permite calcular estatísticas resumidas para cada grupo
Estas funções geralmente trabalham juntas como uma ferramenta poderosa para análise
É como criar “subtotais” ou “relatórios consolidados” por categorias (ex: vendas por região, despesas por departamento)
Sintaxe básica
Cenário: Relatório para executivos sobre desempenho regional
Imagine que você é um analista financeiro e precisa preparar um relatório executivo comparando regiões:
# Cria um relatório de PIB médio por continente
relatorio_continentes <- gapminder %>%
filter(year == 2007) %>% # Filtra para dados mais recentes
group_by(continent) %>% # Agrupa por continente
summarize(
PIB_medio = mean(gdpPercap), # Média do PIB per capita
Total_populacao = sum(pop), # População total
Paises_analisados = n(), # Número de países
PIB_minimo = min(gdpPercap), # PIB mínimo
PIB_maximo = max(gdpPercap) # PIB máximo
) %>%
arrange(desc(PIB_medio)) # Ordena do maior para o menor PIB médio
# Visualiza o resultado
relatorio_continentes
Interpretação Este tipo de relatório consolidado por região é crítico para análises comparativas entre mercados e para apresentações executivas. Mostra claramente as estatísticas-chave para cada grupo (continente), facilitando comparações e decisões estratégicas.
Funções Estatísticas da linguagem R
Função | O que calcula | Exemplo em R | Uso em Negócios |
---|---|---|---|
mean() |
Média | mean(vendas) |
Valor médio de vendas por região |
sum() |
Soma total | sum(receita) |
Receita total por categoria |
min() |
Valor mínimo | min(preco) |
Menor preço praticado |
max() |
Valor máximo | max(despesa) |
Maior despesa do período |
sd() |
Desvio padrão | sd(producao) |
Variabilidade da produção |
n() |
Contagem de linhas | n() |
Número de transações |
n_distinct() |
Contagem de valores únicos | n_distinct(cliente) |
Número de clientes únicos |
median() |
Mediana | median(vendas) |
Valor típico de vendas |
Dica para gestores: Sempre inclua tanto medidas de “tendência central” (média, mediana) quanto de “variação” (desvio padrão) para ter uma visão mais completa dos dados.
Análises mais detalhadas
# Análise de expectativa de vida por continente e ano
tendencias_por_continente <- gapminder %>%
group_by(continent, year) %>% # Agrupa por DUAS variáveis
summarize(
expectativa_vida_media = mean(lifeExp),
paises_analisados = n()
) %>%
arrange(continent, year)
# Mostra resultados parciais
tendencias_por_continente %>%
filter(continent == "Americas") %>%
head(3)
# A tibble: 3 × 4
# Groups: continent [1]
continent year expectativa_vida_media paises_analisados
<fct> <int> <dbl> <int>
1 Americas 1952 53.3 25
2 Americas 1957 56.0 25
3 Americas 1962 58.4 25
Contexto empresarial: Este tipo de análise é comum em:
Os erros que todos cometem no início
Erro | Errado | Correto |
---|---|---|
Não usar summarize após group_by | dados %>% group_by(regiao) |
dados %>% group_by(regiao) %>% summarize(...) |
Tentar agrupar antes de filtrar | group_by(regiao) %>% filter(mean(vendas) > 1000) |
Usar filter() ANTES de group_by()
|
Esquecer de desagrupar | Continuar usando dados agrupados | Usar ungroup() quando terminar com análises agrupadas |
Dica: group_by
por si não produz nenhum resultado.
O que você precisa lembrar
Para que servem:
group_by()
: Agrupa dados por categorias (como agrupar linhas em uma planilha)
summarize()
: Calcula estatísticas para cada grupo (como criar subtotais)
Sintaxe básica:
Funções estatísticas básicas:
Fluxo de trabalho típico:
filter()
)group_by()
)summarize()
)arrange()
)Lembre-se sempre de salvar o resultado:
Exercícios Práticos
Nível 1: Primeiros Passos
Nível 2: Análise de Negócios
Imagine que cada país representa uma filial da sua empresa. Crie um relatório que mostre, para cada continente:
Desafio: Crie um relatório que mostre a evolução da expectativa de vida média do continente americano ao longo dos anos (dica: agrupe por ano, filtre para mostrar apenas as Américas).
Dica: Lembre-se de salvar seus resultados em objetos com nomes descritivos e de usar arrange()
para organizar seus resultados de forma lógica.
Ordena resultados
A função arrange()
ordena as linhas (observações) de uma data frame com base nos valores de uma ou mais colunas (variáveis)
Por padrão, organiza em ordem crescente (do menor para o maior)
Use desc()
para ordenar em ordem decrescente (do maior para o menor)
Reordena as linhas de uma data frame segundo uma variável, por padrão em ordem crescente, com desc() em ordem decrescente
Como usar arrange() na prática
desc()
para ordem descrescente (do maior para o menor)Cenário: Relatório de análise de mercado
Imagine que você é um analista de mercado e precisa identificar rapidamente os países mais promissores para expansão:
# Criando um ranking de países por PIB per capita em 2007
ranking_paises <- gapminder %>%
filter(year == 2007) %>% # Filtra dados apenas de 2007
select(country, continent, gdpPercap) %>% # Seleciona colunas relevantes
arrange(desc(gdpPercap)) %>% # Ordena do maior para o menor PIB
head(6) # Mostra os 10 primeiros resultados
# Visualiza o resultado
ranking_paises
# A tibble: 6 × 3
country continent gdpPercap
<fct> <fct> <dbl>
1 Norway Europe 49357.
2 Kuwait Asia 47307.
3 Singapore Asia 47143.
4 United States Americas 42952.
5 Ireland Europe 40676.
6 Hong Kong, China Asia 39725.
Interpretação Este tipo de ordenação é relevante em análises de mercado para identificar rapidamente os países mais ricos (potenciais mercados premium) ou para encontrar as regiões que precisam de mais atenção (ordenando do menor para o maior).
Cuidados ao usar arrange()
Erro | Problema | Solução |
---|---|---|
Ordem incorreta |
arrange(dados, desc()) sem especificar a variável |
arrange(dados, desc(variavel)) |
Tentar ordenar por variável não existente |
arrange(vendas_por_regiao) quando a coluna não existe |
Verificar primeiro os nomes das colunas com names()
|
Não salvar o resultado ordenado | Ordenar mas não atribuir a um objeto | dados_ordenados <- dados %>% arrange(...) |
Lembre-se: A ordenação é temporária se você não salvar o resultado em um novo objeto!
O que você precisa lembrar
Para que serve: Ordenar as linhas (observações) com base nos valores de uma ou mais colunas
Sintaxe básica:
Usos comuns em negócios:
Lembre-se sempre:
desc()
para ordem decrescentearrange(var1, var2)
Exercícios Práticos
Nível 1: Primeiros Passos
Nível 2: Aplicação em Negócios
Imagine que você trabalha no departamento internacional de uma empresa. Crie uma lista dos países das Américas ordenados por população (do maior para o menor) em 2007.
Desafio: Crie um ranking dos continentes baseado na expectativa de vida média de seus países em 2007. Use group_by(), summarize() e arrange().
Dica: Lembre-se de usar head() para limitar o número de resultados quando necessário!
Resumo das seis funções principais
Função | Propósito |
---|---|
dplyr::filter() |
Seleciona linhas baseadas em condições |
dplyr::select() |
Seleciona colunas específicas |
dplyr::mutate() |
Cria ou modifica colunas |
dplyr::group_by() |
Agrupa dados por categorias |
dplyr::summarize() |
Calcula estatísticas resumidas |
dplyr::arrange() |
Ordena linhas |
Lembre-se: O poder do dplyr está em combinar estas funções com o operador pipe %>%
Vantagens
Com os dados organizados (formato longo), podemos facilmente, por exemplo:
Dados organizados permitem:
Finanças e Controladoria: Análise de tendências financeiras entre períodos, detecção de anomalias em despesas, comparação de desempenho entre unidades de negócio
Marketing: Avaliação de ROI por canal e campanha, análise de comportamento do consumidor, segmentação de clientes baseada em múltiplas variáveis
Operações e Cadeia de Suprimentos: Otimização de estoques baseada em tendências sazonais, previsão de demanda, monitoramento da cadeia de suprimentos
Recursos Humanos: Análise de desempenho ao longo do tempo, identificação de fatores de turnover, planejamento de capacitação
Estratégia de Negócios: Consolidação de KPIs de diversas áreas para tomada de decisão, identificação de correlações entre variáveis de negócio
Na prática: Administradores frequentemente recebem dados em formatos inadequados para análise (relatórios estáticos, planilhas “bonitas”). A capacidade de reorganizar esses dados rapidamente para análise representa uma vantagem competitiva significativa.
Nota
# inicia com a df (gapminder) e salva o resultado final
relatorio_expectativa <- gapminder %>%
# Filtra apenas os dados de 2007
filter(year == 2007) %>%
# Agrupa por continente
group_by(continent) %>%
# Calcula estatísticas por continente
summarize(
expectativa_media = mean(lifeExp),
expectativa_minima = min(lifeExp),
expectativa_maxima = max(lifeExp),
) %>%
# Ordena do maior para o menor
arrange(desc(expectativa_media))
# Visualiza o resultado final
relatorio_expectativa
# A tibble: 5 × 4
continent expectativa_media expectativa_minima expectativa_maxima
<fct> <dbl> <dbl> <dbl>
1 Oceania 80.7 80.2 81.2
2 Europe 77.6 71.8 81.8
3 Americas 73.6 60.9 80.7
4 Asia 70.7 43.8 82.6
5 Africa 54.8 39.6 76.4
Limitações das Data Frames Brutas em Relatórios Profissionais
As data frames produzidas pelos pipelines do dplyr são excelentes para análise, mas não são adequadas para apresentação em relatórios profissionais.
A linguagem R oferece várias soluções para esta limitação:
Estes pacotes permitem transformar dados analíticos em tabelas com qualidade profissional, incluindo:
Transformando tabelas básicas em apresentações profissionais
O pacote kableExtra
estende as funcionalidades da função básica kable
do R, permitindo a criação de tabelas com qualidade de publicação.
Foi desenvolvido para trabalhar com tabelas em documentos HTML e PDF (LaTeX).
Permite formatar tabelas para relatórios profissionais, artigos acadêmicos e apresentações.
É extremamente útil na Fase 6 do CRISP-DM (Implantação), quando precisamos comunicar resultados de forma clara e atrativa.
Fluxo básico com kableExtra
# inicie com uma data frame
tabela_formatada <- dados %>%
# Transforme a data frame em tabela básica
kable(
caption = "Título da Tabela",
col.names = c("Nome1", "Nome2"), # Renomear colunas
digits = 2, # Casas decimais
format.args = list(decimal.mark = ",", big.mark = ".") # Define vírgula como separador decimal e ponto como separador de milhares
) %>%
# Adicionar estilos
kable_styling(
bootstrap_options = c("striped", "hover"),
full_width = FALSE,
position = "center"
)
%>%
)Pipeline para relatórios profissionais
Em projetos de análise de dados completos, o fluxo geralmente é:
tidyr
e dplyr
dplyr
(filter, select, group_by, etc.)ggplot2
(gráficos) e kableExtra
(tabelas)Um pipeline completo pode é similar com:
Este fluxo integrado representa as fases 3, 4 e 6 do CRISP-DM.
Pacote kableExtra
Para que serve: Transformar tabelas de dados simples em tabelas profissionais para relatórios, apresentações e publicações.
Sintaxe básica:
Funções principais:
kable()
: Converte data frame em tabela basekable_styling()
: Aplica estilos gerais à tabelacolumn_spec()
e row_spec()
: Personalizações específicasfootnote()
: Adiciona notas de rodapéIntegrações estratégicas:
Benefícios em Administração:
# inicia com a df contendo o resultado do pipeline
relatorio_expectativa %>%
# Converte a df em uma tabela kable (tabela básica HTML/LaTeX)
kable(
# Renomeia as colunas para português
col.names = c(
"Continente", "Expectativa Média", "Expectativa Mínima", "Expectativa Máxima"
),
# Formata os números com 1 casa decimal
digits = 1,
# vírgula como separador decimal
format.args = list(decimal.mark = ",")
) %>%
# Adiciona estilo à tabela para melhorar o visual
kable_classic(
# tamanho da fonte
font_size = 25,
# Impede que a tabela ocupe toda a largura disponível
full_width = FALSE,
# # Centraliza a tabela
position = "center"
) %>%
# Aplica formatação específica à coluna da expectativa média
column_spec(
# Aplica a formatação à segunda coluna (Expectativa Média)
2,
# Coloca o texto em negrito para melhor destaque
bold = TRUE,
# Define a cor dos números como branco
color = "white",
# Aplica um gradiente de cores ao fundo das células
background = spec_color(
# A expectativa_media determinar a intensidade das cores
relatorio_expectativa$expectativa_media,
# início do gradiente com intensidade alta
begin = 0.9,
# fim do gradiente com intensidade baixa
end = 0.1,
# paleta de cores "viridis" (azul-verde-amarelo)
option = "viridis",
# 1 = valores mais altos recebem cores mais intensas
direction = 1
)
)
relatorio_expectativa %>%
kable(
col.names = c("Continente", "Expectativa Média", "Expectativa Mínima", "Expectativa Máxima"),
digits = 1,
format.args = list(decimal.mark = ",")
) %>%
kable_classic(
font_size = 25,
full_width = FALSE,
position = "center"
) %>%
column_spec(
2,
bold = TRUE,
color = "white",
background = spec_color(
relatorio_expectativa$expectativa_media,
begin = 0.9,
end = 0.1,
option = "viridis",
direction = 1
)
)
Continente | Expectativa Média | Expectativa Mínima | Expectativa Máxima |
---|---|---|---|
Oceania | 80,7 | 80,2 | 81,2 |
Europe | 77,6 | 71,8 | 81,8 |
Americas | 73,6 | 60,9 | 80,7 |
Asia | 70,7 | 43,8 | 82,6 |
Africa | 54,8 | 39,6 | 76,4 |
Dados de Vendas Mensais por Categoria e Produto
# formato típico de planilhas gerenciais
dados_vendas_wide <- tribble(
~produto, ~categoria, ~Jan, ~Fev, ~Mar, ~Abr, ~Mai, ~Jun,
"Notebook Pro", "Eletrônicos", 45000, 38000, 42000, 47000, 52000, 49000,
"Smartphone X", "Eletrônicos", 38000, 41000, 40000, 39000, 45000, 50000,
"Monitor 24pol", "Informática", 22000, 19000, 23000, 25000, 24000, 26000,
"Mouse Gamer", "Informática", 12000, 14000, 13500, 15000, 16000, 17500,
"Mesa Office", "Mobiliário", 28000, 25000, 24000, 26500, 27000, 29000,
"Cadeira Ergo", "Mobiliário", 35000, 32000, 38000, 36000, 39000, 42000
)
# Visualizando os dados no formato amplo (wide)
dados_vendas_wide
# A tibble: 6 × 8
produto categoria Jan Fev Mar Abr Mai Jun
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Notebook Pro Eletrônicos 45000 38000 42000 47000 52000 49000
2 Smartphone X Eletrônicos 38000 41000 40000 39000 45000 50000
3 Monitor 24pol Informática 22000 19000 23000 25000 24000 26000
4 Mouse Gamer Informática 12000 14000 13500 15000 16000 17500
5 Mesa Office Mobiliário 28000 25000 24000 26500 27000 29000
6 Cadeira Ergo Mobiliário 35000 32000 38000 36000 39000 42000
Aplicando pivot_longer para organizar os dados
# Transformando os dados para o formato longo (tidy)
dados_vendas_longo <- dados_vendas_wide %>%
pivot_longer(
cols = Jan:Jun, # colunas que serão transformadas em valores de mes
names_to = "mes", # nome da nova coluna
values_to = "valor_vendas" # nome de outra nova coluna para as vendas
)
# Visualizando o resultado
dados_vendas_longo
# A tibble: 36 × 4
produto categoria mes valor_vendas
<chr> <chr> <chr> <dbl>
1 Notebook Pro Eletrônicos Jan 45000
2 Notebook Pro Eletrônicos Fev 38000
3 Notebook Pro Eletrônicos Mar 42000
4 Notebook Pro Eletrônicos Abr 47000
5 Notebook Pro Eletrônicos Mai 52000
6 Notebook Pro Eletrônicos Jun 49000
7 Smartphone X Eletrônicos Jan 38000
8 Smartphone X Eletrônicos Fev 41000
9 Smartphone X Eletrônicos Mar 40000
10 Smartphone X Eletrônicos Abr 39000
# ℹ 26 more rows
Agora os dados estão organizados para análise:
Análise da Receita Bruta Mensa de Vendas
# pipeline de análise
receita_bruta_mes <- dados_vendas_longo %>%
group_by(mes) %>%
summarize(vendas_total = sum(valor_vendas)) %>%
arrange(desc(vendas_total))
# visualiza o resultado
receita_bruta_mes
# A tibble: 6 × 2
mes vendas_total
<chr> <dbl>
1 Jun 213500
2 Mai 203000
3 Abr 188500
4 Mar 180500
5 Jan 180000
6 Fev 169000
Análise das Vendas Mensais de um Produto Específico
# pipeline de análise
vendas_mensais_notebookpro <- dados_vendas_longo %>%
filter(produto == "Notebook Pro") %>%
select(produto, mes, valor_vendas) %>%
arrange(mes)
# visualiza o resultado
vendas_mensais_notebookpro
# A tibble: 6 × 3
produto mes valor_vendas
<chr> <chr> <dbl>
1 Notebook Pro Abr 47000
2 Notebook Pro Fev 38000
3 Notebook Pro Jan 45000
4 Notebook Pro Jun 49000
5 Notebook Pro Mai 52000
6 Notebook Pro Mar 42000
Análise das Vendas Totais por Categoria e Mês
# pipeline de análise
vendas_totais_categoria_mes <- dados_vendas_longo %>%
group_by(categoria, mes) %>%
summarize(vendas_totais = sum(valor_vendas)) %>%
arrange(desc(vendas_totais))
# visualiza o resultado
vendas_totais_categoria_mes
# A tibble: 18 × 3
# Groups: categoria [3]
categoria mes vendas_totais
<chr> <chr> <dbl>
1 Eletrônicos Jun 99000
2 Eletrônicos Mai 97000
3 Eletrônicos Abr 86000
4 Eletrônicos Jan 83000
5 Eletrônicos Mar 82000
6 Eletrônicos Fev 79000
7 Mobiliário Jun 71000
8 Mobiliário Mai 66000
9 Mobiliário Jan 63000
10 Mobiliário Abr 62500
11 Mobiliário Mar 62000
12 Mobiliário Fev 57000
13 Informática Jun 43500
14 Informática Abr 40000
15 Informática Mai 40000
16 Informática Mar 36500
17 Informática Jan 34000
18 Informática Fev 33000
Análise do Desempenho mensal por produto
# pipeline
desempenho_mensal_produto <- dados_vendas_longo %>%
group_by(produto) %>%
summarize(
vendas_total = sum(valor_vendas),
vendas_media = mean(valor_vendas),
vendas_min = min(valor_vendas),
vendas_max = max(valor_vendas)
) %>%
arrange(desc(vendas_total))
# visualiza o resultado
desempenho_mensal_produto
# A tibble: 6 × 5
produto vendas_total vendas_media vendas_min vendas_max
<chr> <dbl> <dbl> <dbl> <dbl>
1 Notebook Pro 273000 45500 38000 52000
2 Smartphone X 253000 42167. 38000 50000
3 Cadeira Ergo 222000 37000 32000 42000
4 Mesa Office 159500 26583. 24000 29000
5 Monitor 24pol 139000 23167. 19000 26000
6 Mouse Gamer 88000 14667. 12000 17500
# Formata a tabela de desempenho por produto com kableExtra
desempenho_mensal_produto %>%
kable(
# Renomeia as colunas para melhor apresentação
col.names = c(
"Produto",
"Vendas Totais (R$)",
"Média Mensal (R$)",
"Venda Mínima (R$)",
"Venda Máxima (R$)"
),
# Formata números com 2 casas decimais
digits = 2,
# Define vírgula como separador decimal e ponto como separador de milhares
format.args = list(decimal.mark = ",", big.mark = ".", nsmall = 2)
) %>%
# Aplica um estilo clássico e limpo
kable_classic_2(
# Ajusta o tamanho da fonte
font_size = 18,
# Define largura para se ajustar melhor ao slide
full_width = TRUE,
# Centraliza a tabela
position = "center"
) %>%
# Destaca as colunas de valores em negrito
column_spec(2:5, bold = TRUE) %>%
# Destaca as 3 primeiras linha da tabela
row_spec(1:3, bold = T, color = "white", background = "#011f4b")
Produto | Vendas Totais (R$) | Média Mensal (R$) | Venda Mínima (R$) | Venda Máxima (R$) |
---|---|---|---|---|
Notebook Pro | 273.000,00 | 45.500,00 | 38.000,00 | 52.000,00 |
Smartphone X | 253.000,00 | 42.166,67 | 38.000,00 | 50.000,00 |
Cadeira Ergo | 222.000,00 | 37.000,00 | 32.000,00 | 42.000,00 |
Mesa Office | 159.500,00 | 26.583,33 | 24.000,00 | 29.000,00 |
Monitor 24pol | 139.000,00 | 23.166,67 | 19.000,00 | 26.000,00 |
Mouse Gamer | 88.000,00 | 14.666,67 | 12.000,00 | 17.500,00 |
Identificando meses de pico de vendas para cada categoria
# Pipeline para identificar mês de melhor desempenho por categoria
meses_pico_categoria <- dados_vendas_longo %>%
# Agrupa por categoria e mês
group_by(categoria, mes) %>%
# Calcula as vendas totais
summarize(vendas_totais = sum(valor_vendas)) %>%
# Filtra para o mês de maior venda
filter(vendas_totais == max(vendas_totais)) %>%
# Ordena o resultado pelas vendas totais
arrange(desc(vendas_totais))
# visualiza o resultado
meses_pico_categoria
# A tibble: 3 × 3
# Groups: categoria [3]
categoria mes vendas_totais
<chr> <chr> <dbl>
1 Eletrônicos Jun 99000
2 Mobiliário Jun 71000
3 Informática Jun 43500
Identificando meses de pior venda para cada categoria
# Pipeline para identificar mês de pior desempenho por categoria
meses_pior_categoria <- dados_vendas_longo %>%
# Agrupa por categoria e mês
group_by(categoria, mes) %>%
# Calcula as vendas totais
summarize(vendas_totais = sum(valor_vendas)) %>%
# Filtra para o mês de menor venda
filter(vendas_totais == min(vendas_totais)) %>%
# Ordena o resultado pelas vendas totais
arrange(desc(vendas_totais))
# visualiza o resultado
meses_pior_categoria
# A tibble: 3 × 3
# Groups: categoria [3]
categoria mes vendas_totais
<chr> <chr> <dbl>
1 Eletrônicos Fev 79000
2 Mobiliário Fev 57000
3 Informática Fev 33000
Localizando posições de valores máximos e mínimos
As funções which.max()
e which.min()
são extremamente úteis em análise de dados:
which.max(x)
: Retorna a posição (índice) do valor máximo no vetor x
which.min(x)
: Retorna a posição (índice) do valor mínimo no vetor x
Exemplo simples:
# Vetor de valores
vendas_mensais <- c(120, 150, 140, 160, 110, 130)
# Qual a posição do valor máximo?
posicao_max <- which.max(vendas_mensais)
posicao_max
[1] 4
[1] 160
# Supondo que temos nomes para os meses
nomes_meses <- c("Jan", "Fev", "Mar", "Abr", "Mai", "Jun")
# Em qual mês ocorreu a venda máxima?
mes_maior_venda <- nomes_meses[which.max(vendas_mensais)]
mes_maior_venda
[1] "Abr"
Estas funções são perfeitas para encontrar quando ocorreram eventos importantes nos seus dados (máximos, mínimos, picos) em vez de apenas quais foram os valores.
Identificando os Meses de Maior e Menor Venda por Produto
# Pipeline de análise para identificar os meses de pico e vale por produto
resumo_comparativo_produto <- dados_vendas_longo %>%
# Agrupa os dados por produto para analisar cada um separadamente
group_by(produto) %>%
# Para cada produto, calculamos:
summarize(
# 1. Qual o mês da maior venda:
# - which.max(valor_vendas) encontra a POSIÇÃO da maior venda
# - mes[which.max(valor_vendas)] seleciona o nome do mês de maior venda
melhor_mes = mes[which.max(valor_vendas)],
# 2. Qual foi o valor da maior venda
maior_venda = max(valor_vendas),
# 3. Qual o mês da menor venda (mesma lógica do melhor mês)
pior_mes = mes[which.min(valor_vendas)],
# 4. Qual foi o valor da menor venda
menor_venda = min(valor_vendas)
)
# Visualiza o resultado
resumo_comparativo_produto
# A tibble: 6 × 5
produto melhor_mes maior_venda pior_mes menor_venda
<chr> <chr> <dbl> <chr> <dbl>
1 Cadeira Ergo Jun 42000 Fev 32000
2 Mesa Office Jun 29000 Mar 24000
3 Monitor 24pol Jun 26000 Fev 19000
4 Mouse Gamer Jun 17500 Jan 12000
5 Notebook Pro Mai 52000 Fev 38000
6 Smartphone X Jun 50000 Jan 38000
Explicação do código:
Primeiro agrupamos por produto para realizar a análise para cada item
A função which.max(valor_vendas)
retorna a posição (índice) do valor máximo
Ao usar mes[which.max(valor_vendas)]
, extraímos o nome do mês na posição com valor máximo
Este tipo de análise é essencial para identificar padrões sazonais de produtos
Este relatório permite identificar rapidamente quais meses foram melhores e piores para cada produto - informação valiosa para planejamento de estoque e promoções.
Assim, esta análise permite otimizar o planejamento de estoque e ações promocionais sazonais.
# Formata a tabela comparativa com kableExtra
resumo_comparativo_produto %>%
kable(
# Renomeia as colunas para melhor apresentação
col.names = c(
"Produto",
"Melhor Mês",
"Maior Venda (R$)",
"Pior Mês",
"Menor Venda (R$)"
),
# Formata números com 2 casas decimais
digits = 2,
# Define vírgula como separador decimal e ponto como separador de milhares
format.args = list(decimal.mark = ",", big.mark = ".", nsmall = 2)
) %>%
# Aplica um estilo clássico e limpo
kable_paper(
# Ajusta o tamanho da fonte
font_size = 22,
# Define largura para se ajustar melhor ao slide
full_width = FALSE,
# Centraliza a tabela
position = "center"
) %>%
# Destaca as colunas de valores monetários em negrito
column_spec(c(3, 5), bold = TRUE) %>%
# Destaca a quarta linha da tabela
row_spec(4, bold = T, color = "white", background = "#D7261E")
Produto | Melhor Mês | Maior Venda (R$) | Pior Mês | Menor Venda (R$) |
---|---|---|---|---|
Cadeira Ergo | Jun | 42.000,00 | Fev | 32.000,00 |
Mesa Office | Jun | 29.000,00 | Mar | 24.000,00 |
Monitor 24pol | Jun | 26.000,00 | Fev | 19.000,00 |
Mouse Gamer | Jun | 17.500,00 | Jan | 12.000,00 |
Notebook Pro | Mai | 52.000,00 | Fev | 38.000,00 |
Smartphone X | Jun | 50.000,00 | Jan | 38.000,00 |
Reflexão
Considere os dados com os quais você já trabalha ou espera trabalhar em sua carreira:
Que tipos de dados desorganizados você encontra ou espera encontrar?
Como esses dados poderiam ser melhor organizados para análise?
Quais insights de negócio você poderia extrair se esses dados estivessem organizados adequadamente?
Como você aplicaria o conhecimento desta aula em um exemplo concreto do seu interesse profissional?
A Realidade dos Dados Empresariais
Dados corporativos raramente estão em uma única tabela ou sistema:
A tomada de decisão gerencial exige integração desses dados
Exemplo: Para analisar a rentabilidade por cliente, precisamos combinar:
Joins são operações fundamentais para esta integração
Joins na Fase 3 (Preparação dos Dados) do CRISP-DM
Joins são operações fundamentais na Fase 3 (Preparação dos Dados) de CRISP-DM, permitindo:
Integrar dados fragmentados que estão distribuídos em múltiplas tabelas relacionadas entre si
Consolidar informações de diferentes fontes ou sistemas para análise (vendas + produtos + clientes)
Enriquecer dados principais com informações contextuais adicionais (ex: adicionar categoria de produto aos dados de vendas)
Completar o ciclo de preparação iniciado com:
filter()
) e seleção (select()
) de dados relevantesmutate()
) para criar novas variáveispivot_longer()
) para estrutura adequadaDados bem integrados facilitam as Fases 4 e 5 (Modelagem e Avaliação) por fornecerem uma visão completa do problema
O que são joins?
Joins são operações que combinam duas tabelas de dados
Em termos simples, joins são como “colar” duas tabelas lado a lado, combinando linhas que têm valores em comum, como um “código de cliente” ou “código de produto”
No pacote dplyr, temos funções específicas para cada tipo de join:
left_join()
: Mantém todas as linhas da tabela da esquerdainner_join()
: Mantém apenas correspondências entre as tabelasfull_join()
: Mantém todas as linhas de ambas as tabelasright_join()
: Mantém todas as linhas da tabela da direitaSão essenciais quando precisamos combinar informações que estão separadas
Como tabelas se relacionam
Chaves são as colunas usadas para combinar as tabelas
Na prática:
A tabela de clientes tem um “codigo_cliente” único para cada cliente
A tabela de vendas usa esse mesmo “codigo_cliente” para indicar qual cliente fez cada compra
O “codigo_cliente” é a “chave” que permite combinar as informações das duas tabelas
Outros exemplos comuns de chaves:
Nas funções de join do dplyr, as chaves são especificadas pelo argumento by
Contexto Empresarial Simplificado
Vamos trabalhar com um cenário de loja:
# Criando tabela de produtos (simplificada)
produtos <- tribble(
~codigo_produto, ~nome_produto, ~preco_unitario, ~categoria,
"P001", "Notebook Pro", 4500, "Eletrônicos",
"P002", "Smartphone X", 2800, "Eletrônicos",
"P003", "Monitor 24pol", 1200, "Informática",
"P004", "Mouse Gamer", 250, "Informática",
"P005", "Cadeira Ergonômica", 950, "Mobiliário"
)
# Criando tabela de vendas (simplificada)
vendas <- tribble(
~id_venda, ~codigo_produto, ~id_cliente, ~data_venda, ~quantidade,
1, "P001", "C001", "2025-04-15", 1,
2, "P002", "C002", "2025-04-16", 2,
3, "P003", "C001", "2025-04-18", 2,
4, "P002", "C003", "2025-04-20", 1,
5, "P006", "C002", "2025-04-22", 3,
6, "P004", "C004", "2025-04-23", 4
)
# Criando tabela de clientes (simplificada)
clientes <- tribble(
~id_cliente, ~nome_cliente, ~cidade,
"C001", "Empresa Alpha", "São Paulo",
"C002", "Empresa Beta", "Rio de Janeiro",
"C003", "João Silva", "Belo Horizonte",
"C005", "Maria Oliveira", "Recife"
)
Observe que há dados “imperfeitos”:
Como usar joins no dplyr (simplificado)
O que cada parte significa:
vendas
: A primeira tabela (tabela da esquerda)produtos
: A segunda tabela (tabela da direita)by = "codigo_produto"
: A coluna comum que existe em ambas as tabelasleft_join
: O tipo de join que queremos usarvendas_com_produtos
: O resultado da combinação que salvaremosEm resumo:
Tipo de Join | Função no dplyr | Quando usar | Analogia |
---|---|---|---|
Inner join | inner_join() |
Quando você precisa apenas dos registros que existem em ambas as tabelas | Como uma festa onde só entram pessoas que estão nas duas listas de convidados |
Left join | left_join() |
Quando você precisa manter todos os registros da tabela principal (à esquerda) | Como uma festa onde todos os convidados da primeira lista entram, e da segunda lista só entram os que também estão na primeira |
Right join | right_join() |
Quando você precisa manter todos os registros da tabela secundária (à direita) | Como uma festa onde todos os convidados da segunda lista entram, e da primeira lista só entram os que também estão na segunda |
Full join | full_join() |
Quando você precisa de todos os dados, independentemente de correspondências | Como uma festa onde todos os convidados de ambas as listas entram |
Características do Left Join
Mantém todos os registros da tabela da esquerda (primeira tabela)
Para registros sem correspondência na tabela da direita, preenche com NA
Quando usar:
Exemplo: Manter todas as vendas e adicionar dados dos produtos
Left Join entre Vendas e Produtos
# Left join: todas as vendas, mesmo sem correspondência na tabela de produtos
# Passo 1: Pegamos a tabela 'vendas'
# Passo 2: Mantemos TODAS as vendas e adicionamos dados de produtos quando existirem
vendas_produtos_left <- vendas %>%
left_join(produtos, by = "codigo_produto")
# Visualizando o resultado
vendas_produtos_left
# A tibble: 6 × 8
id_venda codigo_produto id_cliente data_venda quantidade nome_produto
<dbl> <chr> <chr> <chr> <dbl> <chr>
1 1 P001 C001 2025-04-15 1 Notebook Pro
2 2 P002 C002 2025-04-16 2 Smartphone X
3 3 P003 C001 2025-04-18 2 Monitor 24pol
4 4 P002 C003 2025-04-20 1 Smartphone X
5 5 P006 C002 2025-04-22 3 <NA>
6 6 P004 C004 2025-04-23 4 Mouse Gamer
# ℹ 2 more variables: preco_unitario <dbl>, categoria <chr>
Observe que:
Agora a venda do produto “P006” (id_venda 5) aparece no resultado
Como esse produto não existe na tabela de produtos, as colunas de produtos aparecem com NA
O left_join é o mais comum em análises gerenciais - preserva todos os registros da tabela principal
Características do Inner Join
Mantém apenas os registros que possuem correspondência em ambas as tabelas
Descarta linhas que não têm correspondência
Quando usar:
Quando você precisa garantir que todos os registros tenham informações completas
Quando registros sem correspondência não são relevantes para sua análise
Exemplo: Relatório de vendas que precisa mostrar dados do produto
Inner Join entre Vendas e Produtos
# Inner join: apenas vendas de produtos que existem no cadastro
# Passo 1: Pegamos a tabela 'vendas'
# Passo 2: Combinamos com a tabela 'produtos' usando codigo_produto
vendas_produtos <- vendas %>%
inner_join(produtos, by = "codigo_produto")
# Visualizando o resultado
vendas_produtos
# A tibble: 5 × 8
id_venda codigo_produto id_cliente data_venda quantidade nome_produto
<dbl> <chr> <chr> <chr> <dbl> <chr>
1 1 P001 C001 2025-04-15 1 Notebook Pro
2 2 P002 C002 2025-04-16 2 Smartphone X
3 3 P003 C001 2025-04-18 2 Monitor 24pol
4 4 P002 C003 2025-04-20 1 Smartphone X
5 6 P004 C004 2025-04-23 4 Mouse Gamer
# ℹ 2 more variables: preco_unitario <dbl>, categoria <chr>
Observe que:
Características do Full Join
Mantém todos os registros de ambas as tabelas
Para registros sem correspondência em qualquer tabela, preenche com NA
Quando usar:
Exemplo: Relatório completo de produtos e vendas
Full Join entre Vendas e Produtos
# Full join: todas as vendas e todos os produtos
# Passo 1: Pegamos a tabela 'vendas'
# Passo 2: Combinamos com produtos mantendo TUDO de ambas as tabelas
completo_vendas_produtos <- vendas %>%
full_join(produtos, by = "codigo_produto")
# Visualizando o resultado
completo_vendas_produtos
# A tibble: 7 × 8
id_venda codigo_produto id_cliente data_venda quantidade nome_produto
<dbl> <chr> <chr> <chr> <dbl> <chr>
1 1 P001 C001 2025-04-15 1 Notebook Pro
2 2 P002 C002 2025-04-16 2 Smartphone X
3 3 P003 C001 2025-04-18 2 Monitor 24pol
4 4 P002 C003 2025-04-20 1 Smartphone X
5 5 P006 C002 2025-04-22 3 <NA>
6 6 P004 C004 2025-04-23 4 Mouse Gamer
7 NA P005 <NA> <NA> NA Cadeira Ergonômica
# ℹ 2 more variables: preco_unitario <dbl>, categoria <chr>
Observe que:
A venda do produto “P006” que não existe na tabela de produtos aparece com NAs
O produto “P005” que não tem vendas também aparece com NAs
O full_join é útil para ver “tudo junto” e identificar inconsistências
Características do Right Join
Mantém todos os registros da tabela da direita (segunda tabela)
Para registros sem correspondência na tabela da esquerda, preenche com NA
Quando usar:
Quando a segunda tabela é sua tabela principal
Quando você precisa garantir que todos os registros da segunda tabela estejam presentes
Na prática, muitas vezes é mais fácil usar left_join invertendo a ordem das tabelas
Exemplo: Ver todos os produtos, mesmo os que não foram vendidos
Right Join entre Vendas e Produtos
# Right join: todos os produtos, mesmo sem vendas
# Passo 1: Pegamos a tabela 'vendas'
# Passo 2: Combinamos com TODOS os produtos, mesmo os sem vendas
produtos_vendas_right <- vendas %>%
right_join(produtos, by = "codigo_produto")
# Visualizando o resultado
produtos_vendas_right
# A tibble: 6 × 8
id_venda codigo_produto id_cliente data_venda quantidade nome_produto
<dbl> <chr> <chr> <chr> <dbl> <chr>
1 1 P001 C001 2025-04-15 1 Notebook Pro
2 2 P002 C002 2025-04-16 2 Smartphone X
3 3 P003 C001 2025-04-18 2 Monitor 24pol
4 4 P002 C003 2025-04-20 1 Smartphone X
5 6 P004 C004 2025-04-23 4 Mouse Gamer
6 NA P005 <NA> <NA> NA Cadeira Ergonômica
# ℹ 2 more variables: preco_unitario <dbl>, categoria <chr>
Observe que:
Identifique o join mais adequado para cada cenário
Para cada situação abaixo, identifique qual tipo de join seria mais apropriado: left_join, inner_join, full_join ou right_join:
Relatório de Vendas: Você precisa criar um relatório mostrando todas as vendas realizadas com detalhes dos produtos. Algumas vendas têm códigos de produtos que não existem no cadastro, mas você precisa manter TODAS as vendas no relatório.
Análise de Estoque: O gerente de inventário solicitou uma lista de todos os produtos cadastrados, indicando quais foram vendidos no último mês. É importante que TODOS os produtos apareçam, mesmo os que não tiveram vendas.
Auditoria de Qualidade: O auditor precisa verificar se há inconsistências entre vendas e produtos. Ele solicitou uma análise que mostre TODAS as vendas e TODOS os produtos, permitindo identificar vendas sem produtos cadastrados e produtos sem vendas.
Dashboard de Performance: O diretor comercial pediu um dashboard que mostre apenas vendas confirmadas com informações completas de cliente e produto. Registros com informações incompletas devem ser excluídos.
Dica: Pense em quais tabelas são “obrigatórias” e quais são “opcionais” em cada cenário!
Respostas
left_join (vendas ⟹ produtos) - Mantém todas as vendas, mesmo sem correspondência na tabela de produtos
right_join (vendas ⟹ produtos) ou left_join ( produtos ⟹ vendas) - Mantém todos os produtos, mesmo sem vendas
full_join - Mantém todos os registros de ambas as tabelas para uma análise completa
inner_join - Mantém apenas registros com correspondência em todas as tabelas
Combinando vendas, produtos e clientes
# Passo 1: Combinamos vendas com produtos
# Passo 2: Depois combinamos o resultado com clientes
relatorio_completo <- vendas %>%
# Primeiro, adicionamos informações de produtos
left_join(produtos, by = "codigo_produto") %>%
# Depois, adicionamos informações de clientes
left_join(clientes, by = "id_cliente") %>%
# Selecionamos apenas as colunas mais importantes para o relatório
select(
id_venda, data_venda,
id_cliente, nome_cliente, cidade,
codigo_produto, nome_produto,
quantidade, preco_unitario
)
# Visualizando o resultado
print(relatorio_completo, n = Inf)
# A tibble: 6 × 9
id_venda data_venda id_cliente nome_cliente cidade codigo_produto nome_produto
<dbl> <chr> <chr> <chr> <chr> <chr> <chr>
1 1 2025-04-15 C001 Empresa Alp… São P… P001 Notebook Pro
2 2 2025-04-16 C002 Empresa Beta Rio d… P002 Smartphone X
3 3 2025-04-18 C001 Empresa Alp… São P… P003 Monitor 24p…
4 4 2025-04-20 C003 João Silva Belo … P002 Smartphone X
5 5 2025-04-22 C002 Empresa Beta Rio d… P006 <NA>
6 6 2025-04-23 C004 <NA> <NA> P004 Mouse Gamer
# ℹ 2 more variables: quantidade <dbl>, preco_unitario <dbl>
Observe como:
Dicas práticas para iniciantes
Conheça seus dados antes de combinar:
Filtre antes de combinar:
Verifique o resultado:
Na dúvida, use left_join:
Lista de vendas com nome do produto
Você precisa criar uma lista simples que mostre, para cada venda, o nome do produto vendido:
id_venda
, data_venda
, nome_produto
e quantidade
# Complete o código
lista_vendas_produtos <- vendas %>%
# 1. Escolha o tipo de join adequado para manter todas as vendas
___(produtos, by = "codigo_produto") %>%
# 2. Selecione apenas as colunas importantes
select(
id_venda,
data_venda,
nome_produto,
quantidade
) %>%
# 3. Ordene por data da venda
arrange(___)
Dica: Pense em qual tipo de join deve usar. Você quer manter todas as vendas mesmo sem produto cadastrado ou apenas as vendas de produtos conhecidos?
Relatório de clientes e suas compras
Crie um relatório que mostre todos os clientes, mesmo aqueles que não fizeram compras:
Una as tabelas de clientes e vendas de forma a manter todos os clientes
Selecione as colunas id_cliente
, nome_cliente
, cidade
, id_venda
e data_venda
Ordene por nome_cliente
# Complete o código
relatorio_clientes <- clientes %>%
# 1. Escolha o tipo de join adequado para manter todos os clientes
___(vendas, by = "id_cliente") %>%
# 2. Selecione apenas as colunas importantes
select(
id_cliente,
nome_cliente,
cidade,
id_venda,
data_venda
) %>%
# 3. Ordene por nome do cliente
arrange(___)
Dica: Como queremos manter todos os clientes, mesmo os que não fizeram compras, qual tipo de join devemos usar?
Calculando e Analisando Lucratividade
O diretor financeiro solicitou um relatório simplificado que mostre o valor total de cada venda:
# Complete o código para calcular o valor total de cada venda
relatorio_financeiro <- vendas %>%
# Combine vendas com produtos usando left_join
left_join(produtos, by = "___") %>%
# Calcule o valor total da venda
mutate(valor_total = ___) %>%
# Selecione apenas as colunas relevantes para o relatório
select(
id_venda,
data_venda,
codigo_produto,
nome_produto,
quantidade,
preco_unitario,
valor_total
) %>%
# Ordene do maior valor total para o menor
arrange(___)
Perguntas para reflexão:
Situação Comum em Ambientes Empresariais
No mundo ideal, todos os sistemas usariam os mesmos nomes para as mesmas informações…
Mas na prática:
codigo_produto
codigo
cod_prod
id_produto
Resultado: Tentar unir estas tabelas com a sintaxe básica falha:
Como resolver este problema comum?
Sintaxe para Colunas com Nomes Diferentes
O dplyr permite especificar explicitamente quais colunas devem ser correspondidas:
Como interpretar:
"nome_na_tabela1"
: Nome da coluna na primeira tabela (esquerda)"nome_na_tabela2"
: Nome da coluna na segunda tabela (direita)=
estabelece a correspondência entre as colunasAnalogia: Você está criando um “dicionário de tradução” entre os sistemas:
codigo_produto
, você entende codigo
”Cenário: Relatório de Vendas Integrado
# Sistema de Cadastro de Produtos (departamento de Compras)
produtos_cadastro <- tribble(
~codigo, ~descricao, ~valor_unitario, ~categoria,
"P001", "Notebook Pro", 4500, "Eletrônicos",
"P002", "Smartphone X", 2800, "Eletrônicos",
"P003", "Monitor 24pol", 1200, "Informática"
)
# Sistema de Vendas (departamento Comercial)
vendas_sistema <- tribble(
~id_venda, ~cod_produto, ~data_venda, ~qtd,
1, "P001", "2025-04-15", 1,
2, "P002", "2025-04-16", 2,
3, "P003", "2025-04-18", 2
)
# Integrando os sistemas com diferentes nomenclaturas
relatorio_vendas <- vendas_sistema %>%
left_join(produtos_cadastro, by = c("cod_produto" = "codigo")) %>%
select(id_venda, data_venda, cod_produto, descricao, qtd, valor_unitario) %>%
mutate(valor_total = qtd * valor_unitario) %>%
arrange(data_venda)
# Resultado: um relatório integrado
relatorio_vendas
# A tibble: 3 × 7
id_venda data_venda cod_produto descricao qtd valor_unitario valor_total
<dbl> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 1 2025-04-15 P001 Notebook Pro 1 4500 4500
2 2 2025-04-16 P002 Smartphone X 2 2800 5600
3 3 2025-04-18 P003 Monitor 24pol 2 1200 2400
Observação: Esta situação é extremamente comum.
Pontos-chave para lembrar
Joins unem tabelas que estão separadas
Os tipos mais importantes são:
left_join()
: Mantém todos os registros da tabela principal (o mais usado)inner_join()
: Mantém apenas registros com correspondência em ambas tabelasfull_join()
: Mantém todos os registros de ambas as tabelasNa prática, left_join é o mais comum:
Comece simples e avance gradualmente:
Guia Rápido de Joins no dplyr
Tipo de Join | Função | Resultado | Quando Usar | Analogia de Negócios |
---|---|---|---|---|
Inner Join | inner_join() |
Apenas registros com correspondência | Análises que exigem dados completos | Relatório com apenas vendas confirmadas |
Left Join | left_join() |
Todos os registros da tabela esquerda | Manter a tabela principal intacta | Relatório de todas as vendas (com ou sem produto cadastrado) |
Right Join | right_join() |
Todos os registros da tabela direita | Quando a 2ª tabela é a principal | Catálogo com todos os produtos (vendidos ou não) |
Full Join | full_join() |
Todos os registros de ambas as tabelas | Análises completas e auditorias | Verificação de inconsistências no sistema |
Dica para lembrar: Pense no “lado” que você quer preservar:
Estrutura comum dos diferentes tipos de joins
# LEFT JOIN: todos os registros da tabela1
tabela1 %>%
left_join(tabela2, by = "coluna_comum")
# INNER JOIN: apenas registros com correspondência
tabela1 %>%
inner_join(tabela2, by = "coluna_comum")
# FULL JOIN: todos os registros de ambas as tabelas
tabela1 %>%
full_join(tabela2, by = "coluna_comum")
# RIGHT JOIN: todos os registros da tabela2
tabela1 %>%
right_join(tabela2, by = "coluna_comum")
Observe que:
A estrutura básica é idêntica para todos os joins:
%>%
Só muda o nome da função, que indica qual tipo de join realizar:
inner_join
, left_join
, right_join
ou full_join
Quando as colunas têm nomes diferentes, use esta sintaxe:
Aplicações práticas em Administração
Finanças:
Marketing:
Recursos Humanos:
Logística:
Vendas:
Instruções
Prof. Washington Silva - Introdução à Ciência de Dados