Introdução à Linguagem R

R
Reprodutibilidade

Um tutorial básico sobre a linguagem R para Ciência de Dados.

Autor
Afiliação

Prof. Dr. Washington S. da Silva

Data de Publicação

7 julho 2024

1 Introdução

Objetivos
  • Este tutorial é destinado aos estudantes do bacharelado em Administração e aos mestrandos do Mestrado Profissional em Administração do IFMG - Campus Formiga.

  • Também é útil para administradores, economistas, contabilistas, auditores e outros profissionais que desejam utilizar ferramentas modernas para criar relatórios e outros produtos de forma reproduzível e auditável.

  • O objetivo principal é proporcionar uma compreensão sólida da linguagem R, desde seus fundamentos até aplicações em análise de dados, permitindo que alunos de graduação, mestrandos e demais profissionais e pesquisadores interessados desenvolvam habilidades para criar análises reproduzíveis e auditáveis. Embora o foco inicial seja a Ciência de Dados aplicada à Administração, o conteúdo foi elaborado para ser útil em diversas áreas do conhecimento.

Instalando a Linguagem R 4.4.1
  1. Acesse https://cloud.r-project.org/

  2. Selecione o sistema operacional, clicando em Download R for Windows por exemplo.

  3. Na página seguinte clique em base.

  4. Clique em Download R-4.4.3 for Windows.

  5. Feito o download basta ir clicando em próximo/next até a instalação ser concluída.

RStudio: Ambiente de Desenvolvimento para R
  • Para uma experiência de programação mais produtiva com R, recomenda-se fortemente o uso do RStudio, um IDE (Ambiente de Desenvolvimento Integrado) especialmente projetado para trabalhar com a linguagem R.

  • O RStudio oferece diversas funcionalidades que facilitam o aprendizado e uso da linguagem, como editor de código com destaque de sintaxe, projetos Rstudio, integração com Git e suporte nativo ao sistema Quarto.

  • Para instalar e configurar o RStudio, consulte nosso Tutorial sobre RStudio, onde são apresentadas instruções detalhadas para iniciantes.

  • Embora seja perfeitamente possível utilizar R com outros IDEs, a combinação (R + RStudio) facilita e potencializa significativamente a experiência de aprendizado e desenvolvimento.

O que é R?
  • R é um ambiente ou sistema para computação estatística e gráfico.

  • Este sistema é composto por duas partes: a própria linguagem R (que é o que a maioria das pessoas querem dizer quando falam sobre R) e um ambiente de tempo de execução (runtime environment).

  • R é uma linguagem interpretada, o que significa que os usuários acessam suas funções por meio de um interpretador de linha de comando.

  • Ao contrário de linguagens como Python e Java, R não é uma linguagem de programação de uso geral.

  • Em vez disso, R é considerada uma linguagem de domínio específica (DSL), o que significa que suas funções e uso foram projetados para uma área específica de uso ou domínio.

  • No caso de R, o domínio e a computação estatística. Por extensão, R é comumente usada para todos os tipos de tarefas de ciência de dados.

  • A linguagem R está equipada com um grande conjunto de funções internas para a manipulação, análise e visualização de dados.

  • Além das funções internas da linguagem, existem inúmeros pacotes (como os módulos de Python) que estendem as capacidades da linguagem.

Origens da Linguagem R

A linguagem S

  • A linguagem S foi desenvolvida em meados da década de 1970 por John Chambers no lendário Bell Labs. O objetivo era oferecer uma abordagem interativa para a computação estatística, que fosse fácil de usar e tornasse as tarefas de análise de dados mais fáceis e rápidas.

  • Em uma entrevista de 2013, Chambers observou que a equipe do Bell Labs queria que as pessoas começassem em um ambiente interativo, onde não pensassem em si como programadores. Então, à medida que suas necessidades se tornaram mais claras e sua sofisticação aumentasse, eles dseriam capazes de se orientar gradualmente para a programação com a linguagem S.

  • A filosofia geral de S era muito semelhante à de R: oferecer um ambiente de software que facilitasse a programação computacional e a análise estatística, que qualquer um possa aprender a usar.

  • Como R, S também pode ser usada para escrever programas mais longos centrados em tarefas estatísticas. Ao contrário de R, no entanto, S e sua iteração posterior, S-Plus, eram produtos licenciados, o que significa que tinham que ser comprados de uma empresa.

  • Portanto, é importante notar que a linguagem R é um dialeto da linguagem S.

Sintáxe e Semântica

  • Os linguistas usam os termos sintaxe e semântica para descrever elementos de linguagens naturais, e os cientistas da computação também adotaram esses termos para linguagens de programação.

  • Na programação de computadores, a sintaxe se refere às regras que ditam a ‘ortografia’ e a ‘gramática’ de uma linguagem, enquanto a semântica se refere a como os dados ou comandos de uma linguagem são apresentados.

  • A sintaxe de R era muito semelhante à de S em seus primeiros anos. Isso tornou mais fácil para as pessoas que usavam S-Plus mudar para R, o que desempenhou um papel fundamental na eventual popularidade de R na academia.

  • A semântica de R, no entanto, está mais próxima da linguagem Scheme, uma linguagem de programação funcional.

R é uma linguagem de baixo ou alto nível?

  • R é considerada uma linguagem de programação de alto nível. Essa classificação é baseada em seu nível de abstração da linguagem de máquina.

  • Ao contrário das linguagens de baixo nível que exigem conhecimento aprofundado da memória e dos processos do computador, linguagens de alto nível como R são projetadas para serem facilmente compreendidas e escritas por humanos, tornando-as mais acessíveis para estatísticos, analistas de dados e pesquisadores.

Um Breve Histórico da Linguagem R
  • 1991: Os professores e estatísticos Ross Ihaka e Robert Gentleman começam a trabalhar em um novo dialeto da linguagem S como um projeto de pesquisa para o Departamento de Estatística da Universidade de Auckland na Nova Zelândia.

  • 1993: O primeiro anúncio de R chega ao público através do arquivo de dados StatLib e da lista de discussão s-news.

  • 1995: O estatístico Martin Mächler convence os criadodes de R a lançar a linguagem sob uma licença pública geral GNU, tornando R gratuita e de código aberto. Ihaka e Gentleman lançam seu artigo seminal apresentando R ao mundo.

  • 1997: O R Core Team foi formado, este grupo é o único com acesso ao código-fonte R. No mesmo ano, foi criada a Comprehensive R Archive Network (CRAN). Este repositório de pacotes R ajuda os profissionais em inúmeras tarefas.

  • 2000: R versão 1.0.0 foi lançada ao público.

  • Março de 2024: Estamos atualmente na versão R 4.3.3

Por que usar a linguagem R?
  • Gratuito e de código aberto: Diferentemente de softwares estatísticos proprietários, R é completamente gratuito e seu código-fonte é aberto, permitindo total transparência e personalização.

  • Especialmente projetado para análise estatística e ciência de dados: Enquanto outras linguagens podem ser adaptadas para estas tarefas, R foi concebida especificamente para computação estatística e visualização de dados.

  • Ampla comunidade acadêmica e profissional: R possui uma comunidade ativa de usuários que contribuem constantemente com novos pacotes, métodos e soluções para problemas complexos.

  • Integração com o sistema Quarto: Perfeita compatibilidade com o sistema de publicação Quarto, permitindo a criação de documentos, apresentações e websites dinâmicos e reproduzíveis.

  • Ecossistema Tidyverse: O conjunto de pacotes Tidyverse fornece uma gramática consistente para manipulação, visualização e modelagem de dados, especialmente útil para iniciantes.

  • Excelência em visualização de dados: Pacotes como ggplot2 permitem criar visualizações estatísticas sofisticadas e personalizáveis.

  • Relevância no mercado: Profissionais com conhecimento em R são valorizados em setores como finanças, consultorias, pesquisa de mercado e análise de negócios.

  • Reprodutibilidade científica: R facilita a implementação de práticas de ciência reproduzível, essencial para pesquisas acadêmicas e relatórios corporativos auditáveis.

  • Versatilidade em tipos de análise: Desde estatísticas descritivas simples até modelos complexos de machine learning e econometria aplicada, R oferece ferramentas para diversos níveis de análise.

  • Documentação extensa: Ampla disponibilidade de documentação, tutoriais, livros e recursos online, facilitando o aprendizado contínuo.

Vídeo sobre R
  • Para finalizar esta introdução, assista o vídeo a seguir sobre a linguagem R disponibilizado pelo R Consortium:
Próximos Passos

Nas próximas seções do tutorial vamos explorar os conceitos básicos da linguagem R, que servirão como alicerce para os tópicos posteriores. Compreender esses fundamentos é essencial antes de avançarmos para análises mais complexas.

2 Objetos e Variáveis em R

Em R, os termos “variável” e “objeto” são frequentemente usados de forma intercambiável, o que pode causar confusão inicial, especialmente para quem já possui experiência com outras linguagens de programação. Esta seção esclarece essa terminologia para facilitar seu aprendizado.

A Filosofia “Tudo é um Objeto” em R

R segue uma filosofia fundamental: tudo que existe em R é um objeto. Isso significa que todos os elementos que você manipula — desde números simples até funções complexas — são tratados como objetos.

Esta abordagem difere de muitas outras linguagens de programação que fazem distinção clara entre “variáveis primitivas” (como números) e “objetos” (estruturas mais complexas).

Quando criamos algo em R usando um operador de atribuição (<-), estamos essencialmente:

  1. Criando um objeto na memória do computador
  2. Atribuindo um nome a esse objeto para referenciá-lo posteriormente

Por exemplo, em idade <- 25, criamos um objeto do tipo numérico com valor 25 e o nomeamos como “idade”. Este nome funciona como uma etiqueta que nos permite acessar e manipular o objeto.

Por que usarei “variável” e “objeto” de forma intercambiável?

Por questões de clareza e para facilitar seu aprendizado:

  • Utilizarei o termo variável principalmente quando falarmos de valores simples que “variam”, como números, textos ou valores lógicos. Este termo é mais intuitivo para iniciantes e comum em estatística e análise de dados.

  • Utilizarei o termo objeto quando precisarmos enfatizar a natureza mais complexa de algumas estruturas em R, como data frames, listas, funções ou quando discutirmos conceitos mais avançados.

  • Em muitos contextos, usarei ambos os termos de forma intercambiável, refletindo a prática comum na comunidade R.

Esta flexibilidade terminológica espelha a documentação oficial da linguagem R e a literatura sobre a linguagem, preparando você para diferentes materiais que poderá encontrar em sua jornada de aprendizado.

Uma Analogia Útil

Imagine uma biblioteca onde cada livro é um “objeto” de dados:

  • O conteúdo do livro representa os dados ou valores armazenados.

  • O título na lateral representa o nome da variável

  • As prateleiras e estantes representam a memória do computador

  • O catálogo da biblioteca equivale ao ambiente R, que mantém registro de onde cada objeto está armazenado

Quando você cria uma variável como receita <- 5000, é como se estivesse colocando um novo livro (com o conteúdo “5000”) na biblioteca e rotulando sua lateral como “receita” para poder encontrá-lo depois.

Este entendimento sobre variáveis e objetos em R estabelece uma base conceitual importante antes de mergulharmos nos tipos específicos de dados e em como manipulá-los para análises eficazes.

3 Variáveis e Atribuição de Valores

Em R, a atribuição de valores a variáveis é fundamental para armazenar e manipular dados. Por exemplo, podemos criar variáveis para armazenar informações financeiras, como receitas, custos e lucros, que são essenciais para análises em Administração.

# Exemplo: Atribuição de valores a variáveis
receita_mensal <- 850000  # Receita mensal da empresa
custos_mensais <- 500000  # Custos mensais

# Cálculo do lucro
lucro_mensal <- receita_mensal - custos_mensais  
lucro_mensal
[1] 350000

Todas as instruções R com as quais criamos variáveis ou objetos têm o mesmo formato:

nome_do_objeto <- valor

Lemos esse código como: “valor é atribuído a nome_objeto

Em R, podemos atribuir informações às variáveis (ou objetos) utilizando os seguintes operadores de atribuição:

# Diferentes formas de atribuição em R
# Mesmo resultado, estilos diferentes

# Operador recomendado (<-) 
receita_mensal <- 850000
receita_mensal
[1] 850000
# Alternativa (=), funciona, mas menos 
# recomendado
lucro_operacional = 320000
lucro_operacional
[1] 320000

Em R, como em todas as linguagens, fazemos muitas atribuições de valores a variáveis, e não é agradável digitar o operador manualmente. Assim, o RStudio oferece um atalho de teclado simples para inserir o operador <-:

  • Atalho do RStudio: Alt + - (Windows/Linux) ou Option + - (Mac)

  • Observe que o RStudio automaticamente envolve <- com espaços, o que é uma boa prática de formatação de código.

  • Códigos sem espaços são difíceis de ler compare:

lucro<-receita-custos versus

lucro <- receita - custos

Boas Práticas para Escrever Códigos R

Nomes de variáveis devem começar com uma letra e podem conter letras, números, _ e .

É importante criar nomes de objetos simples e descritivos que representem claramente seu conteúdo. Em Administração, é comum trabalhar com dados financeiros, de desempenho ou de mercado, então use nomes que facilitem a compreensão do código.

Exemplos de boas práticas:

# Margem bruta da empresa
margem_bruta <- 0.35  

# Fluxo de caixa operacional
fluxo_caixa_operacional <- receita - custos  

Estilos de nomenclatura:

  • snake_case: margem_bruta, fluxo_caixa_operacional
  • CamelCase: MargemBruta, FluxoCaixaOperacional

Escolha um estilo e mantenha a consistência em todo o código.

Práticas a evitar

Evite os seguintes erros comuns:

  1. Nomes genéricos:
  • Ruim: dados, resultado, x
  • Melhor: receita_anual, lucro_liquido
  1. Nomes muito longos:
  • Ruim: calculo_da_margem_de_contribuicao_ajustada
  • Melhor: margem_contribuicao
  1. Espaços nos nomes:
  • Ruim: margem bruta <- 0.35 (causa erro)
  • Melhor: margem_bruta <- 0.35
  1. Nomes começando com números:
  • Ruim: 1trimestre <- "Janeiro-Março" (inválido)
  • Melhor: trimestre1 <- "Janeiro-Março"
  1. Sobrescrever funções existentes:
  • Ruim: mean <- 10 (sobrescreve a função mean())
  • Melhor: media <- 10
Como Imprimir Informações sobre Objetos em R

Em R, existem algumas formas simples e eficazes de exibir informações sobre objetos ou variáveis. Esses métodos são ideais para visualizar valores, depurar código ou criar saídas personalizadas. Abaixo estão as principais formas:

1. Usando print()

A função print() é a maneira mais básica de exibir o conteúdo de um objeto:

# Exemplo: Usando print()
receita <- 850000.50
print(receita)  # Exibe o valor da variável
[1] 850000.5

2. Imprimindo diretamente no console

Em R, você pode exibir o conteúdo de um objeto simplesmente digitando seu nome no console. Isso chama automaticamente a função print() implicitamente:

# digitar o nome do objeto exibe seu valor
receita  
[1] 850000.5

3. Usando a função cat()

A função cat() permite exibir informações de forma mais personalizada, combinando texto e valores. É útil para criar mensagens ou relatórios simples.

# a funçaão cat() combina texto e valor
cat("A receita mensal é:", receita)  
A receita mensal é: 850000.5

Resumo:

  • Use print() para exibir valores de forma explícita.

  • Digite o nome do objeto diretamente no console para exibir seu valor de forma rápida.

  • Use cat() para criar saídas personalizadas, combinando texto e valores.

4 Tipos Atômicos de Dados

Em R, os dados são armazenados em diferentes tipos atômicos (básicos), cada um com características específicas. A Tabela 3 mostra os principais tipos.

Tabela 1: Principais Tipos
Tipo Classe Descrição
double numeric um vetor contendo valores reais (números com casas decimais)
integer numeric um vetor contendo valores inteiros (números sem casas decimais)
character character um vetor contendo valores de texto (caracteres)
logical logical um vetor contendo valores lógicos (TRUE/FALSE)

A Tabela 2 exibe alguns tipos especiais que podem aparecer em análises de dados.

Tabela 2: Tipos Especiais
Tipo Descrição
NA Not Available: representa dados faltantes
NaN Not a Number: (ex: 0 / 0)
Inf + \infty ou - \infty: (ex: 1 / 0)
A Importância de Conhecer Tipos e Classes de Dados

Na prática da Ciência de Dados, estima-se que analistas e cientistas dedicam entre 60% a 80% do tempo de um projeto à importação, limpeza e preparação dos dados antes de iniciar análises mais sofisticadas. Compreender profundamente os tipos e classes de dados em R é fundamental por várias razões:

  • Evita erros sutis de processamento: Operações matemáticas em dados textuais ou cálculos com valores ausentes podem produzir resultados inesperados.

  • Otimiza o desempenho: Estruturas de dados apropriadas melhoram a eficiência computacional, especialmente em conjuntos grandes.

  • Facilita transformações: O conhecimento dos tipos permite conversões adequadas (como texto para número) sem perda de informação.

  • Melhora a interpretabilidade: Identificar corretamente dados faltantes (NA), indefinidos (NaN), ou infinitos (Inf) é crucial para conclusões válidas.

  • Aumenta a compatibilidade: Diferentes funções e pacotes em R exigem tipos específicos de dados como entrada.

O domínio dos tipos e classes de dados não é apenas uma questão técnica, mas um requisito fundamental para análises confiáveis em contextos administrativos e financeiros. Este conhecimento permite ao analista de dados concentrar-se mais nos insights e menos na correção de problemas estruturais nos dados.

4.1 Tipos double e integer

Em R, existem dois tipos principais de dados numéricos:

  • double: Armazena números com casas decimais (ponto flutuante), ideal para valores monetários, índices financeiros, taxas percentuais e outras medidas que exigem precisão decimal.

  • integer: Armazena números inteiros sem casas decimais, útil para contagens, quantidades discretas e índices em séries temporais.

Na prática de Administração e Finanças, o tipo double é frequentemente utilizado para representar valores monetários, taxas de juros ou indicadores financeiros, enquanto integer é mais comum para representar quantidades como número de funcionários, produtos vendidos ou períodos de análise.

O sufixo L após um número (como em 50L) indica explicitamente que se trata de um valor inteiro. Na maioria das operações, R utiliza automaticamente o tipo mais apropriado, o que simplifica a programação para análises financeiras e administrativas.

# double (números com casas decimais)
receita <- 850000.50  

# integer (números inteiros)
total_funcionarios <- 50L   

# verifica os tipos
typeof(receita)
[1] "double"
typeof(total_funcionarios)
[1] "integer"
classe numeric

Apesar dos tipos double e integer representarem números decimais e inteiros de forma diferente, ambos pertencem à classe numeric, assim, na maioria das situações, você não precisa se preocupar com a possível diferença.

class(receita)
[1] "numeric"
class(total_funcionarios)
[1] "integer"

Diferença entre typeof e class

Em R, as funções typeof e class fornecem informações diferentes sobre um objeto:

  • typeof: Retorna o tipo interno do objeto, ou seja, como R armazena o objeto na memória. Por exemplo:
typeof(receita)  # Retorna "double"
typeof(total_funcionarios)  # Retorna "integer"
  • class: Retorna a classe do objeto, que define como R trata o objeto em operações e funções. Por exemplo:
class(receita)  # Retorna "numeric"
class(total_funcionarios)  # Retorna "numeric"

Em resumo:

  • Use typeof para entender como R armazena o objeto internamente.
  • Use class para entender como R trata o objeto em operações e funções.

4.2 Tipo character

O tipo character é essencial para armazenar e manipular informações textuais. Este tipo de dado armazena sequências de caracteres (texto) e é indicado por aspas simples (') ou duplas (").

Em contextos de Administração, o tipo character é utilizado para armazenar:

  • Nomes de empresas, setores ou produtos
  • Categorias em classificações de mercado
  • Períodos de tempo expressos como texto (Ex: “1° Trimestre 2024”)
  • Códigos de identificação alfanuméricos
  • Observações qualitativas

A manipulação de dados textuais é particularmente importante em análises de mercado, pesquisas de satisfação, classificação de produtos e organização de relatórios gerenciais, onde a categorização textual precede análises quantitativas.

# character (texto)
instituicao <- "IFMG - Campus Formiga" 

# verifica o tipo 
typeof(instituicao)
[1] "character"

4.3 Tipo logical

O tipo logical representa valores booleanos (TRUE ou FALSE) e é fundamental para operações condicionais e filtragem de dados.

Em contextos práticos de gestão e finanças, o tipo logical é utilizado para:

  • Verificar condições financeiras (Ex: lucro positivo, meta atingida)
  • Filtrar dados que atendem a critérios específicos
  • Automatizar decisões baseadas em regras de negócio
  • Sinalizar eventos importantes (Ex: inadimplência, quebra de estoque)
  • Implementar validações em modelos de previsão

Os valores TRUE e FALSE devem ser escritos em maiúsculas em R, e podem ser abreviados como T e F, respectivamente, embora a forma completa seja recomendada para maior clareza do código.

# logical (lógico, TRUE/FALSE)
lucro_positivo <- TRUE  
lucro_negativo <- FALSE

# verifica o tipo 
typeof(lucro_positivo)
[1] "logical"
typeof(lucro_negativo)
[1] "logical"

4.4 Tipo Especial NA

O tipo especial NA (Not Available) é comum em análises de dados reais, onde frequentemente nos deparamos com informações ausentes. Em contextos de Administração e Finanças, dados faltantes podem representar:

  • Vendas não realizadas em determinados períodos
  • Informações contábeis pendentes
  • Valores não reportados em demonstrações financeiras
  • Respostas omitidas em pesquisas de mercado
  • Métricas não aplicáveis a certos departamentos ou produtos

Identificar e tratar corretamente os valores NA é essencial para evitar conclusões tendenciosas. R oferece funções específicas como is.na() para detectar valores ausentes e métodos estatísticos para lidar com eles de forma apropriada.

# Exemplo: Detectando valores ausentes em dados de vendas 
vendas_trimestrais <- c(150000, 165000, NA, 180000)
is.na(vendas_trimestrais) 
[1] FALSE FALSE  TRUE FALSE
# calculando a média excluindo valores ausentes
mean(vendas_trimestrais, na.rm = TRUE)
[1] 165000

O tratamento adequado de dados falantes é uma habilidade fundamental em Ciência de Dados.

4.5 Tipo Especial NaN

O valor NaN (Not a Number) ocorre quando uma operação matemática produz um resultado indefinido. Em contextos de gestão e finanças, este tipo especial pode surgir em:

  • Cálculos de indicadores financeiros com divisores zero
  • Operações matemáticas inválidas em modelos preditivos
  • Transformações logarítmicas de valores negativos ou zero
  • Raízes quadradas de números negativos em análises estatísticas

Enquanto NA representa dados ausentes, NaN indica especificamente um resultado numérico indefinido. Diferenciá-los é importante para diagnóstico de problemas em cálculos complexos, como em modelos de precificação de ativos ou simulações financeiras.

A função is.nan() permite identificar estes valores em conjuntos de dados:

# Exemplo: Identificando resultados indefinidos em cálculos financeiros
resultados <- c(25, 0/0, 10)
is.nan(resultados)  
[1] FALSE  TRUE FALSE

4.6 Tipo Especial inf

O valor especial Inf (e -Inf para infinito negativo) ocorre principalmente em divisões por zero e representa valores que excedem os limites computacionais. Em análises administrativas e financeiras, este tipo pode aparecer em:

  • Cálculos de taxas de crescimento a partir de valores base zero
  • Razões financeiras com denominadores muito próximos a zero
  • Projeções exponenciais sem restrições
  • Análises de retorno sobre investimento com investimentos mínimos

Diferentemente de NA e NaN, valores Inf podem ser utilizados em operações aritméticas seguindo regras matemáticas de infinito:

# Exemplo: Comportamento de infinito em operações
infinito_positivo <- 1/0
infinito_positivo + 1000  # Continua sendo Inf
[1] Inf
infinito_positivo / 2     # Continua sendo Inf
[1] Inf

Identificar valores infinitos é importante, por exemplo, em modelos financeiros, pois podem indicar problemas estruturais nas fórmulas utilizadas ou divisões por zero que comprometem a validade das análises.

Sobre Conversão entre Tipos e Classes de Dados
  • Você pode estar se perguntando como converter um tipo ou classe de dados em outro(a) (por exemplo, transformar um texto em número ou vice-versa).

  • Embora R base ofereça funções como as.numeric(), as.character() e as.logical() para essas conversões, abordaremos este tópico mais adiante no tutorial, quando estudarmos a manipulação de dados com o pacote dplyr.

  • Especificamente, aprenderemos como usar as funções mutate() e transmute() para realizar conversões de tipos de maneira eficiente e legível em conjuntos de dados estruturados. Esta abordagem se alinha com as práticas modernas de ciência de dados e permite transformar múltiplas variáveis simultaneamente dentro de um fluxo de trabalho analítico coerente.

  • Por enquanto, foque em compreender as características e comportamentos dos diferentes tipos de dados apresentados nesta seção, pois este conhecimento fundamentará toda sua jornada na análise de dados com R.

5 Estruturas de Dados em R

Fundamentos das Estruturas de Dados

Em R, os dados são organizados em diferentes estruturas, cada uma adequada a tipos específicos de operações e análises. As principais estruturas de dados são:

  • Vetores: Sequências unidimensionais de elementos homogêneos.
  • Matrizes: Estruturas bidimensionais homogêneas.
  • Data Frames: Estruturas bidimensionais heterogêneas, semelhantes a tabelas.
  • Tibbles: Versões modernas e mais robustas dos data frames.
  • Listas: Estruturas flexíveis que podem conter diferentes tipos de objetos simultaneamente.

A compreensão dessas estruturas facilita uma escolha eficiente para diferentes contextos analíticos, sendo essencial para utilizar efetivamente os pacotes e recursos avançados do R.

5.1 Vetores

Importância dos Vetores
  • Vetores são a estrutura fundamental do R.
  • Toda variável simples no R é, por definição, um vetor com comprimento mínimo igual a 1.
  • Os elementos em um vetor são sempre do mesmo tipo (homogêneos).
  • Dominar vetores é essencial para compreender estruturas mais complexas, como data frames e listas.

5.1.1 Criação de Vetores

A função básica para criar vetores é c(), que concatena valores.

# Vetor numérico simples
dados <- c(3.5, 4.2, 6.7, 2.3)

# Sequência de números inteiros de 1 a 10
sequencia <- 1:10

# Sequência espaçada uniformemente de 0 a 1 com intervalo 0.25
intervalos <- seq(0, 1, by = 0.25)

# Repetição de um valor lógico
status <- rep(TRUE, times = 5)
Coerção implícita em vetores

Se você combinar tipos diferentes em um mesmo vetor, R converte automaticamente todos os elementos para um único tipo mais flexível:

c(5, "R", TRUE)  # Todos convertidos para "character"
[1] "5"    "R"    "TRUE"

5.1.2 Indexação de Vetores

Utilize colchetes [] para selecionar elementos. Lembre-se de que a indexação no R começa por 1.

# Primeiro elemento do vetor
dados[1]
[1] 3.5
# Último elemento do vetor
dados[length(dados)]
[1] 2.3
# Removendo o terceiro elemento
dados[-3]
[1] 3.5 4.2 2.3
# Selecionando elementos maiores que 4
dados[dados > 4]
[1] 4.2 6.7

5.1.3 Funções Matemáticas Aplicadas a Vetores

R possui diversas funções que facilitam cálculos matemáticos e estatísticos diretamente aplicáveis a vetores. Algumas essenciais são:

numeros <- c(1, 3, 5, 7, 9)

# Soma dos elementos
sum(numeros)
[1] 25
# Soma acumulada
cumsum(numeros)
[1]  1  4  9 16 25
# Produto dos elementos
prod(numeros)
[1] 945
# Produto acumulado
cumprod(numeros)
[1]   1   3  15 105 945
# Logaritmo natural dos elementos
log(numeros)
[1] 0.000000 1.098612 1.609438 1.945910 2.197225
# Exponencial dos elementos
exp(numeros)
[1]    2.718282   20.085537  148.413159 1096.633158 8103.083928
# Média
mean(numeros)
[1] 5
# Mediana
median(numeros)
[1] 5
# Desvio padrão
sd(numeros)
[1] 3.162278
# Variância
var(numeros)
[1] 10
# Valor mínimo
min(numeros)
[1] 1
# Valor máximo
max(numeros)
[1] 9

Essas funções são especialmente úteis em aplicações estatísticas e econométricas, como o cálculo de retornos médios, dispersão de dados financeiros ou identificação de extremos em séries temporais.

5.1.4 Operações Vetorizadas e Reciclagem

Operações matemáticas são aplicadas diretamente em vetores, permitindo grande eficiência:

retornos <- c(0.02, 0.05, -0.03, 0.04)

# Descontando uma taxa fixa (por exemplo, imposto de 10%)
retornos_liquidos <- retornos * (1 - 0.10)

# Usando reciclagem (taxas alternadas)
taxas <- c(0.10, 0.15)
retornos_alternados <- retornos * (1 - taxas)
Atenção ao comportamento da reciclagem

Se o comprimento dos vetores for incompatível, R recicla o vetor mais curto, o que pode gerar resultados inesperados:

c(1, 2, 3) + c(10, 20)  # Resultado ambíguo, com aviso
[1] 11 22 13

5.1.5 Tipos e Comprimento dos Vetores

Sempre verifique o tipo e comprimento dos vetores para evitar problemas na análise:

typeof(retornos)   # tipo interno do vetor
[1] "double"
class(retornos)    # classe do objeto
[1] "numeric"
length(retornos)   # número de elementos
[1] 4

5.1.6 Vetores de Texto e Lógicos

Além de numéricos, vetores podem conter caracteres (texto) ou valores lógicos:

# Vetor de caracteres
instituicoes <- c("IFMG", "UFV", "USP")

# Vetor lógico indicando se metas foram atingidas
metas_atingidas <- c(TRUE, FALSE, TRUE)

5.1.7 Boas Práticas com Vetores

  • Defina vetores homogêneos e com nomes claros.
  • Use typeof() e class() para checar e evitar coerções não desejadas.
  • Evite coerções implícitas acidentais mantendo elementos do mesmo tipo no vetor.

5.2 Matrizes

Matrizes são estruturas bidimensionais que organizam elementos homogêneos em linhas e colunas. Em análises estatísticas, econométricas e métodos numéricos, matrizes desempenham papel central, especialmente devido à eficiência computacional nas operações de álgebra linear.

5.2.1 Características Fundamentais

  • Homogeneidade: Todos os elementos têm o mesmo tipo.
  • Bidimensionalidade: Estrutura formada por linhas e colunas.
  • Indexação: Elementos acessados por [linha, coluna].
  • Operações otimizadas: Eficientes para cálculos matriciais.

5.2.2 Criação de Matrizes em R

Em R, matrizes são criadas com a função matrix(). Esta função recebe um vetor de dados e distribui-os em uma matriz especificando o número de linhas (nrow) ou colunas (ncol). O parâmetro byrow define se o preenchimento será feito por linhas (TRUE) ou por colunas (FALSE, padrão).

# Criação por linhas
A <- matrix(c(4, 2, 1,
              3, 5, 2,
              1, 2, 6), nrow = 3, byrow = TRUE)

# Criação por colunas (default)
B <- matrix(c(2, 1, 2,
              1, 4, 1,
              3, 2, 5), nrow = 3)

A
     [,1] [,2] [,3]
[1,]    4    2    1
[2,]    3    5    2
[3,]    1    2    6
B
     [,1] [,2] [,3]
[1,]    2    1    3
[2,]    1    4    2
[3,]    2    1    5
# Matriz econométrica simulada
set.seed(123)
X <- matrix(c(rep(1, 5), 2:6, seq(1.5, 3.5, 0.5)), nrow = 5)
colnames(X) <- c("Intercepto", "X1", "X2")
X
     Intercepto X1  X2
[1,]          1  2 1.5
[2,]          1  3 2.0
[3,]          1  4 2.5
[4,]          1  5 3.0
[5,]          1  6 3.5

5.2.3 Operações Aritméticas com Matrizes

As operações básicas entre matrizes ocorrem elemento a elemento ou por meio de multiplicação matricial:

# Operações elemento a elemento
A + B
     [,1] [,2] [,3]
[1,]    6    3    4
[2,]    4    9    4
[3,]    3    3   11
A - B
     [,1] [,2] [,3]
[1,]    2    1   -2
[2,]    2    1    0
[3,]   -1    1    1
A * B
     [,1] [,2] [,3]
[1,]    8    2    3
[2,]    3   20    4
[3,]    2    2   30
A / B
     [,1] [,2]      [,3]
[1,]  2.0 2.00 0.3333333
[2,]  3.0 1.25 1.0000000
[3,]  0.5 2.00 1.2000000
# Multiplicação por escalar
3 * A
     [,1] [,2] [,3]
[1,]   12    6    3
[2,]    9   15    6
[3,]    3    6   18
# Multiplicação matricial
A %*% B
     [,1] [,2] [,3]
[1,]   12   13   21
[2,]   15   25   29
[3,]   16   15   37
# Matriz transposta
t(A)
     [,1] [,2] [,3]
[1,]    4    3    1
[2,]    2    5    2
[3,]    1    2    6

5.2.4 Determinante e Inversa

O determinante indica se uma matriz quadrada é invertível (determinante diferente de zero). A inversa de uma matriz A é a matriz A^{-1} tal que A A^{-1} = I, onde I é a matriz identidade.

det(A)
[1] 73
# Inversa de A
solve(A)
            [,1]        [,2]        [,3]
[1,]  0.35616438 -0.13698630 -0.01369863
[2,] -0.21917808  0.31506849 -0.06849315
[3,]  0.01369863 -0.08219178  0.19178082

5.2.5 Matrizes Especiais

R permite criar matrizes especiais úteis em aplicações específicas:

# Matriz identidade 3x3
diag(3)
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1
# Matriz diagonal
D <- diag(c(2, 5, 3))
D
     [,1] [,2] [,3]
[1,]    2    0    0
[2,]    0    5    0
[3,]    0    0    3
# Extração da diagonal de uma matriz
diag(A)
[1] 4 5 6
# Matrizes triangulares
A * upper.tri(A, diag = TRUE)  # Triangular superior
     [,1] [,2] [,3]
[1,]    4    2    1
[2,]    0    5    2
[3,]    0    0    6
A * lower.tri(A, diag = TRUE)  # Triangular inferior
     [,1] [,2] [,3]
[1,]    4    0    0
[2,]    3    5    0
[3,]    1    2    6

5.2.6 Autovalores e Autovetores

Para uma matriz quadrada A, um autovalor \lambda e seu respectivo autovetor v satisfazem:

A v = \lambda v

eigen_A <- eigen(A)

eigen_A$values  # Autovalores
[1] 8.758770 4.305407 1.935822
round(eigen_A$vectors, 3)  # Autovetores
       [,1]   [,2]   [,3]
[1,] -0.410 -0.418 -0.623
[2,] -0.661 -0.457  0.751
[3,] -0.628  0.785 -0.216

5.2.7 Decomposições Matriciais

Decomposições matriciais facilitam cálculos complexos e análises estruturais, expressando matrizes como produtos de outras com propriedades específicas.

5.2.7.1 Decomposição QR

Expressa uma matriz A como A = QR, onde Q é ortogonal e R é triangular superior.

qr_A <- qr(A)
Q <- qr.Q(qr_A)
R <- qr.R(qr_A)

Q
           [,1]       [,2]        [,3]
[1,] -0.7844645  0.6167038  0.06551218
[2,] -0.5883484 -0.7066397 -0.39307307
[3,] -0.1961161 -0.3468959  0.91717049
R
         [,1]      [,2]      [,3]
[1,] -5.09902 -4.902903 -3.137858
[2,]  0.00000 -2.993583 -2.877951
[3,]  0.00000  0.000000  4.782389

5.2.7.2 Decomposição por Valores Singulares (SVD)

Expressa qualquer matriz A como A = U D V', onde U e V são ortogonais e D é diagonal contendo valores singulares.

svd_A <- svd(A)
U <- svd_A$u
D <- diag(svd_A$d)
V <- svd_A$v

# Reconstrução de A
U %*% D %*% t(V)
     [,1] [,2] [,3]
[1,]    4    2    1
[2,]    3    5    2
[3,]    1    2    6

5.2.8 Aplicação Econométrica: Estimação por MQO

No modelo de regressão linear múltipla Y = X \beta + \varepsilon, a estimativa por Mínimos Quadrados Ordinários (MQO) é dada por:

\hat{\beta} = (X'X)^{-1} X'Y

set.seed(789)
n <- 100
X_reg <- cbind(1, rnorm(n), rnorm(n))
beta_real <- c(2, 1.5, -0.8)
Y <- X_reg %*% beta_real + rnorm(n)

beta_est <- solve(t(X_reg) %*% X_reg) %*% t(X_reg) %*% Y
beta_est
           [,1]
[1,]  1.9064582
[2,]  1.5857319
[3,] -0.8492812

5.3 Listas

Listas são as estruturas mais flexíveis do R, fundamentais em econometria para armazenar resultados de simulações, outputs de modelos estatísticos e organizar dados de diferentes tipos e dimensões. São especialmente úteis em simulações de Monte Carlo e no desenvolvimento de funções econométricas personalizadas.

5.3.1 Características das Listas

  • Heterogeneidade: Podem conter elementos de tipos diferentes (números, matrizes, data frames, outras listas)
  • Flexibilidade: Cada elemento pode ser de qualquer classe ou estrutura
  • Aninhamento: Podem conter outras listas (estruturas hierárquicas)
  • Nomeação: Elementos podem ter nomes para acesso facilitado
  • Armazenamento de resultados: Ideais para guardar outputs complexos de análises

5.3.2 Criando Listas para Análises Econométricas

# Lista para armazenar resultados de um modelo de regressão
set.seed(123)
n <- 100
X <- cbind(1, rnorm(n), rnorm(n))  # Matriz de regressores
beta_true <- c(2, 1.5, -0.8)      # Parâmetros verdadeiros
epsilon <- rnorm(n, 0, 2)          # Termo de erro
Y <- X %*% beta_true + epsilon     # Variável dependente

# Estimação do modelo
XtX_inv <- solve(t(X) %*% X)
beta_hat <- XtX_inv %*% t(X) %*% Y
residuos <- Y - X %*% beta_hat
sigma2_hat <- sum(residuos^2) / (n - ncol(X))

# Armazenando resultados em uma lista
resultado_regressao <- list(
  coeficientes = as.vector(beta_hat),
  matriz_covariancia = sigma2_hat * XtX_inv,
  residuos = as.vector(residuos),
  R_quadrado = 1 - sum(residuos^2) / sum((Y - mean(Y))^2),
  graus_liberdade = n - ncol(X),
  observacoes = n,
  dados = list(X = X, Y = Y)
)

# Visualizando a estrutura da lista
str(resultado_regressao)
List of 7
 $ coeficientes      : num [1:3] 2.27 1.234 -0.752
 $ matriz_covariancia: num [1:3, 1:3] 0.03697 -0.00376 0.00403 -0.00376 0.04399 ...
 $ residuos          : num [1:100] 4.012 2.281 -0.374 0.852 -1.019 ...
 $ R_quadrado        : num 0.346
 $ graus_liberdade   : num 97
 $ observacoes       : num 100
 $ dados             :List of 2
  ..$ X: num [1:100, 1:3] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ Y: num [1:100, 1] 6.13 4.07 4.01 3.47 2.13 ...

5.3.3 Acessando Elementos de Listas

# Acesso por nome com $
resultado_regressao$coeficientes
[1]  2.2701309  1.2336569 -0.7523774
# Acesso por nome com [[]]
resultado_regressao[["R_quadrado"]]
[1] 0.3462614
# Acesso por índice
resultado_regressao[[4]]  # R-quadrado
[1] 0.3462614
# Acesso a elementos aninhados
resultado_regressao$dados$Y[1:5]  # Primeiras 5 observações de Y
[1] 6.125232 4.074053 4.005126 3.470185 2.126547
# Múltiplos elementos (retorna uma lista)
resultado_regressao[c("coeficientes", "R_quadrado")]
$coeficientes
[1]  2.2701309  1.2336569 -0.7523774

$R_quadrado
[1] 0.3462614

5.3.4 Simulação de Monte Carlo com Listas

# Função para simulação de Monte Carlo
simulacao_regressao <- function(n, beta_true, sigma, n_sim = 1000) {
  
  # Lista para armazenar resultados de cada simulação
  resultados <- list()
  
  for(i in 1:n_sim) {
    # Gerando dados
    X <- cbind(1, rnorm(n), rnorm(n))
    epsilon <- rnorm(n, 0, sigma)
    Y <- X %*% beta_true + epsilon
    
    # Estimando parâmetros
    beta_hat <- solve(t(X) %*% X) %*% t(X) %*% Y
    
    # Armazenando resultado da i-ésima simulação
    resultados[[i]] <- list(
      beta_hat = as.vector(beta_hat),
      iteracao = i
    )
  }
  
  return(resultados)
}

# Executando simulação (versão reduzida para demonstração)
set.seed(456)
sim_resultados <- simulacao_regressao(
  n = 50, 
  beta_true = c(1, 2, -1), 
  sigma = 1, 
  n_sim = 100
)

# Analisando resultados da simulação
betas_simulados <- sapply(sim_resultados, function(x) x$beta_hat)
media_betas <- rowMeans(betas_simulados)

cat("Parâmetros verdadeiros:", c(1, 2, -1), "\n")
Parâmetros verdadeiros: 1 2 -1 
cat("Média das estimativas:", round(media_betas, 3), "\n")
Média das estimativas: 1.013 2 -1.002 
cat("Número de simulações:", length(sim_resultados), "\n")
Número de simulações: 100 

5.3.5 Organizando Resultados de Múltiplos Modelos

# Função para estimar e comparar diferentes modelos
comparar_modelos <- function(Y, X1, X2, X3) {
  
  # Modelo 1: apenas X1
  modelo1 <- lm(Y ~ X1)
  
  # Modelo 2: X1 e X2
  modelo2 <- lm(Y ~ X1 + X2)
  
  # Modelo 3: X1, X2 e X3
  modelo3 <- lm(Y ~ X1 + X2 + X3)
  
  # Organizando resultados em lista
  comparacao <- list(
    modelo_1 = list(
      coeficientes = coef(modelo1),
      R2 = summary(modelo1)$r.squared,
      AIC = AIC(modelo1),
      n_parametros = length(coef(modelo1))
    ),
    modelo_2 = list(
      coeficientes = coef(modelo2),
      R2 = summary(modelo2)$r.squared,
      AIC = AIC(modelo2),
      n_parametros = length(coef(modelo2))
    ),
    modelo_3 = list(
      coeficientes = coef(modelo3),
      R2 = summary(modelo3)$r.squared,
      AIC = AIC(modelo3),
      n_parametros = length(coef(modelo3))
    ),
    criterios_selecao = data.frame(
      Modelo = c("Modelo 1", "Modelo 2", "Modelo 3"),
      R2 = c(summary(modelo1)$r.squared, 
             summary(modelo2)$r.squared, 
             summary(modelo3)$r.squared),
      AIC = c(AIC(modelo1), AIC(modelo2), AIC(modelo3))
    )
  )
  
  return(comparacao)
}

# Gerando dados para demonstração
set.seed(789)
n <- 80
X1 <- rnorm(n)
X2 <- rnorm(n)
X3 <- rnorm(n)
Y <- 2 + 1.5*X1 + 0.8*X2 + rnorm(n, 0, 1)

# Executando comparação
resultados_comparacao <- comparar_modelos(Y, X1, X2, X3)

# Acessando resultados
print("Critérios de Seleção:")
[1] "Critérios de Seleção:"
print(resultados_comparacao$criterios_selecao)
    Modelo        R2      AIC
1 Modelo 1 0.5164472 280.1806
2 Modelo 2 0.7801518 219.1228
3 Modelo 3 0.7872469 218.4984
cat("\nR² do melhor modelo:", 
    max(resultados_comparacao$criterios_selecao$R2), "\n")

R² do melhor modelo: 0.7872469 

5.3.6 Armazenando Resultados de Testes Econométricos

# Função para realizar múltiplos testes diagnósticos
testes_diagnosticos <- function(modelo) {
  
  # Teste de normalidade dos resíduos (Shapiro-Wilk)
  teste_normalidade <- shapiro.test(residuals(modelo))
  
  # Teste de heterocedasticidade (Breusch-Pagan simplificado)
  residuos2 <- residuals(modelo)^2
  valores_ajustados <- fitted(modelo)
  teste_hetero <- summary(lm(residuos2 ~ valores_ajustados))
  
  # Organizando resultados em lista estruturada
  diagnosticos <- list(
    normalidade = list(
      estatistica = teste_normalidade$statistic,
      p_valor = teste_normalidade$p.value,
      interpretacao = ifelse(teste_normalidade$p.value > 0.05, 
                           "Resíduos seguem distribuição normal", 
                           "Evidência contra normalidade")
    ),
    heterocedasticidade = list(
      R2 = teste_hetero$r.squared,
      F_estatistica = teste_hetero$fstatistic[1],
      interpretacao = ifelse(teste_hetero$r.squared < 0.1, 
                           "Não há evidência de heterocedasticidade", 
                           "Possível heterocedasticidade")
    ),
    resumo_modelo = list(
      R2_ajustado = summary(modelo)$adj.r.squared,
      erro_padrao = summary(modelo)$sigma,
      observacoes = nobs(modelo)
    )
  )
  
  return(diagnosticos)
}

# Aplicando função de testes
modelo_exemplo <- lm(Y ~ X1 + X2)
resultados_testes <- testes_diagnosticos(modelo_exemplo)

# Visualizando resultados
str(resultados_testes, max.level = 2)
List of 3
 $ normalidade        :List of 3
  ..$ estatistica  : Named num 0.973
  .. ..- attr(*, "names")= chr "W"
  ..$ p_valor      : num 0.0887
  ..$ interpretacao: chr "Resíduos seguem distribuição normal"
 $ heterocedasticidade:List of 3
  ..$ R2           : num 0.00434
  ..$ F_estatistica: Named num 0.34
  .. ..- attr(*, "names")= chr "value"
  ..$ interpretacao: chr "Não há evidência de heterocedasticidade"
 $ resumo_modelo      :List of 3
  ..$ R2_ajustado: num 0.774
  ..$ erro_padrao: num 0.923
  ..$ observacoes: int 80
print(resultados_testes$normalidade$interpretacao)
[1] "Resíduos seguem distribuição normal"
print(resultados_testes$heterocedasticidade$interpretacao)
[1] "Não há evidência de heterocedasticidade"

5.4 Data Frames

Fundamentos das Estruturas Tabulares

As estruturas tabulares organizam informações em formato de tabela, com linhas representando observações e colunas representando variáveis. Data frames e tibbles constituem a base para a maioria das análises estatísticas e financeiras.

Estas estruturas permitem:

  • Armazenar dados heterogêneos (números, textos, valores lógicos) de forma organizada
  • Aplicar operações estatísticas e transformações por variável
  • Integrar-se com pacotes especializados para análises avançadas
  • Facilitar a importação e exportação de dados de diversas fontes

Diferentemente das matrizes (homogêneas), data frames e tibbles permitem colunas de tipos diferentes, sendo ideais para conjuntos de dados típicos em administração e finanças.

O data frame é a estrutura de dados mais utilizada em R para análises estatísticas. Conceptualmente similar a uma planilha, um data frame organiza dados em formato retangular onde cada linha representa uma observação e cada coluna representa uma variável.

5.4.1 Características Fundamentais

Um data frame possui as seguintes características essenciais:

  • Estrutura retangular: Todas as colunas devem ter o mesmo comprimento
  • Colunas heterogêneas: Cada coluna pode conter um tipo diferente de dados
  • Colunas homogêneas: Dentro de cada coluna, todos os elementos devem ser do mesmo tipo
  • Indexação: Linhas e colunas podem ser acessadas por índices numéricos ou nomes

5.4.2 Criando Data Frames

A função data.frame() permite criar estruturas tabulares combinando vetores de mesmo comprimento:

# Dados de desempenho empresarial
empresa <- c("TechCorp", "FinanceMax", "RetailPlus")
receita_milhoes <- c(125.8, 89.3, 156.7)
crescimento_percentual <- c(12.5, -3.2, 8.9)
meta_atingida <- c(TRUE, FALSE, TRUE)

# Criando o data frame
desempenho_empresas <- data.frame(
  empresa = empresa,
  receita_milhoes = receita_milhoes,
  crescimento_percentual = crescimento_percentual,
  meta_atingida = meta_atingida
)

# Exibindo o resultado
desempenho_empresas
     empresa receita_milhoes crescimento_percentual meta_atingida
1   TechCorp           125.8                   12.5          TRUE
2 FinanceMax            89.3                   -3.2         FALSE
3 RetailPlus           156.7                    8.9          TRUE

5.4.3 Estrutura e Propriedades

Para compreender a estrutura interna de um data frame, utilizamos funções específicas:

# Estrutura detalhada do objeto
str(desempenho_empresas)
'data.frame':   3 obs. of  4 variables:
 $ empresa               : chr  "TechCorp" "FinanceMax" "RetailPlus"
 $ receita_milhoes       : num  125.8 89.3 156.7
 $ crescimento_percentual: num  12.5 -3.2 8.9
 $ meta_atingida         : logi  TRUE FALSE TRUE
# Dimensões: linhas e colunas
dim(desempenho_empresas)
[1] 3 4
# Nomes das colunas
names(desempenho_empresas)
[1] "empresa"                "receita_milhoes"        "crescimento_percentual"
[4] "meta_atingida"         
# Nomes das linhas
rownames(desempenho_empresas)
[1] "1" "2" "3"

5.4.4 Acesso a Dados

R oferece múltiplas formas de acessar elementos em data frames:

# Acessando uma coluna específica pelo nome
desempenho_empresas$receita_milhoes
[1] 125.8  89.3 156.7
# Acessando múltiplas colunas
desempenho_empresas[c("empresa", "receita_milhoes")]
     empresa receita_milhoes
1   TechCorp           125.8
2 FinanceMax            89.3
3 RetailPlus           156.7
# Acessando por índices: linha 2, coluna 3
desempenho_empresas[2, 3]
[1] -3.2
# Filtrando observações por condição
desempenho_empresas[desempenho_empresas$meta_atingida == TRUE, ]
     empresa receita_milhoes crescimento_percentual meta_atingida
1   TechCorp           125.8                   12.5          TRUE
3 RetailPlus           156.7                    8.9          TRUE

5.4.5 Resumo Estatístico

Para análises preliminares, a função summary() fornece estatísticas descritivas:

summary(desempenho_empresas)
   empresa          receita_milhoes crescimento_percentual meta_atingida  
 Length:3           Min.   : 89.3   Min.   :-3.200         Mode :logical  
 Class :character   1st Qu.:107.5   1st Qu.: 2.850         FALSE:1        
 Mode  :character   Median :125.8   Median : 8.900         TRUE :2        
                    Mean   :123.9   Mean   : 6.067                        
                    3rd Qu.:141.2   3rd Qu.:10.700                        
                    Max.   :156.7   Max.   :12.500                        

5.5 Tibbles

Tibbles são uma versão modernizada dos data frames, desenvolvida como parte do ecosistema tidyverse. Mantêm compatibilidade com data frames tradicionais, mas incorporam melhorias significativas para análise de dados contemporânea.

5.5.1 Principais Vantagens dos Tibbles

Melhorias em Relação aos Data Frames
  • Exibição otimizada: Apresenta automaticamente apenas as primeiras linhas e colunas, evitando sobrecarga visual
  • Informações de tipos: Exibe o tipo de cada coluna na visualização
  • Comportamento previsível: Evita conversões automáticas indesejadas (como texto para fator)
  • Performance superior: Operações mais eficientes com conjuntos grandes de dados
  • Integração com tidyverse: Compatibilidade total com pacotes modernos de análise

5.5.2 Convertendo Data Frames para Tibbles

library(tibble)

# Convertendo o data frame em tibble
desempenho_tibble <- as_tibble(desempenho_empresas)

# Exibindo o tibble
desempenho_tibble
# A tibble: 3 × 4
  empresa    receita_milhoes crescimento_percentual meta_atingida
  <chr>                <dbl>                  <dbl> <lgl>        
1 TechCorp             126.                    12.5 TRUE         
2 FinanceMax            89.3                   -3.2 FALSE        
3 RetailPlus           157.                     8.9 TRUE         

5.5.3 Criando Tibbles Diretamente

A função tibble() oferece uma sintaxe mais moderna para criação:

# Criando tibble com dados financeiros trimestrais
resultados_trim <- tibble(
  trimestre = c("Q1", "Q2", "Q3", "Q4"),
  receita = c(2.8, 3.1, 3.5, 4.2),
  margem_bruta = c(0.32, 0.35, 0.38, 0.41),
  roi = receita * margem_bruta / 2.5  # Calculando ROI diretamente
)

resultados_trim
# A tibble: 4 × 4
  trimestre receita margem_bruta   roi
  <chr>       <dbl>        <dbl> <dbl>
1 Q1            2.8         0.32 0.358
2 Q2            3.1         0.35 0.434
3 Q3            3.5         0.38 0.532
4 Q4            4.2         0.41 0.689

5.5.4 Inspeção Avançada de Tibbles

O tibble oferece funções específicas para inspeção detalhada:

# Visão geral compacta - função do pacote dplyr
glimpse(resultados_trim)
Rows: 4
Columns: 4
$ trimestre    <chr> "Q1", "Q2", "Q3", "Q4"
$ receita      <dbl> 2.8, 3.1, 3.5, 4.2
$ margem_bruta <dbl> 0.32, 0.35, 0.38, 0.41
$ roi          <dbl> 0.3584, 0.4340, 0.5320, 0.6888
# Verificando tipos de dados de cada coluna individualmente
class(resultados_trim$trimestre)
[1] "character"
class(resultados_trim$receita)
[1] "numeric"
class(resultados_trim$margem_bruta)
[1] "numeric"
class(resultados_trim$roi)
[1] "numeric"

5.5.5 Detecção de Valores Ausentes

Para análises robustas, é fundamental identificar dados faltantes:

# Criando tibble com alguns valores ausentes para demonstração
dados_com_na <- tibble(
  empresa = c("Alpha", "Beta", "Gamma", "Delta"),
  vendas = c(150, NA, 180, 165),
  custo = c(120, 140, NA, 135),
  lucro = vendas - custo
)

# Visualizando o tibble
dados_com_na
# A tibble: 4 × 4
  empresa vendas custo lucro
  <chr>    <dbl> <dbl> <dbl>
1 Alpha      150   120    30
2 Beta        NA   140    NA
3 Gamma      180    NA    NA
4 Delta      165   135    30
# Contando valores ausentes por coluna usando loop
for(coluna in names(dados_com_na)) {
  na_count <- sum(is.na(dados_com_na[[coluna]]))
  cat("Coluna", coluna, ":", na_count, "valores ausentes\n")
}
Coluna empresa : 0 valores ausentes
Coluna vendas : 1 valores ausentes
Coluna custo : 1 valores ausentes
Coluna lucro : 2 valores ausentes
# Identificando linhas com algum valor ausente
dados_com_na[!complete.cases(dados_com_na), ]
# A tibble: 2 × 4
  empresa vendas custo lucro
  <chr>    <dbl> <dbl> <dbl>
1 Beta        NA   140    NA
2 Gamma      180    NA    NA

5.6 Exemplo Prático com Dados Financeiros Reais

Para demonstrar a aplicação prática dessas estruturas, utilizaremos dados reais de performance de carteiras do pacote PerformanceAnalytics:

library(PerformanceAnalytics)
library(tidyverse)

# Carregando dados de retornos de gestores e benchmarks
data(managers, package = "PerformanceAnalytics")

# Convertendo para tibble e preservando datas
retornos_gestores <- as_tibble(managers, rownames = "data")

# Exibindo estrutura dos dados
glimpse(retornos_gestores)
Rows: 132
Columns: 11
$ data          <chr> "1996-01-31", "1996-02-29", "1996-03-31", "1996-04-30", …
$ HAM1          <dbl> 0.0074, 0.0193, 0.0155, -0.0091, 0.0076, -0.0039, -0.023…
$ HAM2          <dbl> NA, NA, NA, NA, NA, NA, NA, -0.0001, 0.1002, 0.0338, 0.0…
$ HAM3          <dbl> 0.0349, 0.0351, 0.0258, 0.0449, 0.0353, -0.0303, -0.0337…
$ HAM4          <dbl> 0.0222, 0.0195, -0.0098, 0.0236, 0.0028, -0.0019, -0.044…
$ HAM5          <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ HAM6          <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ `EDHEC LS EQ` <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.0281, …
$ `SP500 TR`    <dbl> 0.0340, 0.0093, 0.0096, 0.0147, 0.0258, 0.0038, -0.0442,…
$ `US 10Y TR`   <dbl> 0.00380, -0.03532, -0.01057, -0.01739, -0.00543, 0.01507…
$ `US 3m TR`    <dbl> 0.00456, 0.00398, 0.00371, 0.00428, 0.00443, 0.00412, 0.…

5.6.1 Análise Inicial dos Dados

# Verificando período de análise
range(retornos_gestores$data, na.rm = TRUE)
[1] "1996-01-31" "2006-12-31"
# Contando observações válidas por gestor (excluindo valores ausentes)
cat("Observações válidas por coluna:\n")
Observações válidas por coluna:
for(coluna in names(retornos_gestores)[-1]) {  # Excluindo coluna 'data'
  obs_validas <- sum(!is.na(retornos_gestores[[coluna]]))
  cat(coluna, ":", obs_validas, "observações\n")
}
HAM1 : 132 observações
HAM2 : 125 observações
HAM3 : 132 observações
HAM4 : 132 observações
HAM5 : 77 observações
HAM6 : 64 observações
EDHEC LS EQ : 120 observações
SP500 TR : 132 observações
US 10Y TR : 132 observações
US 3m TR : 132 observações
# Estatísticas descritivas dos primeiros três gestores
summary(retornos_gestores[2:4])
      HAM1                HAM2               HAM3          
 Min.   :-0.094400   Min.   :-0.03710   Min.   :-0.071800  
 1st Qu.:-0.000025   1st Qu.:-0.00980   1st Qu.:-0.005375  
 Median : 0.011150   Median : 0.00820   Median : 0.010200  
 Mean   : 0.011123   Mean   : 0.01414   Mean   : 0.012447  
 3rd Qu.: 0.024850   3rd Qu.: 0.02520   3rd Qu.: 0.031375  
 Max.   : 0.069200   Max.   : 0.15560   Max.   : 0.179600  
                     NA's   :7                             

5.6.2 Preparação para Análises Avançadas

Este conjunto de dados será utilizado nas próximas seções para demonstrar:

  • Manipulação de dados com dplyr
  • Visualizações com ggplot2
  • Análises de performance e risco
  • Modelos econométricos aplicados
Consolidação do Aprendizado

Nesta seção estabelecemos os fundamentos das principais estruturas de dados em R:

  • Matrizes: Estruturas bidimensionais homogêneas, ideais para cálculos matemáticos e operações de álgebra linear
  • Listas: Estruturas flexíveis que permitem armazenar objetos de diferentes tipos e complexidades
  • Data frames: Estruturas tabulares fundamentais para análise estatística com colunas heterogêneas
  • Tibbles: Evolução moderna dos data frames com melhorias práticas para ciência de dados

Critérios para Escolha da Estrutura:

  • Use matrizes para operações matemáticas com dados homogêneos
  • Use listas para armazenar resultados complexos ou dados hierárquicos
  • Use data frames/tibbles para análises estatísticas com dados tabulares heterogêneos

Compreender quando e como utilizar cada estrutura é fundamental para desenvolver análises eficientes e código limpo em contextos administrativos e financeiros.

6 Metapacote tidyverse

Descrição
  • O tidyverse é um ecossistema coerente de pacotes R para ciência de dados que compartilham uma filosofia de design e gramática comuns.

  • Desenvolvido por Hadley Wickham e mantido pela Posit, o tidyverse facilita todo o fluxo de trabalho de análise de dados através de pacotes integrados.

Alguns dos Principais Pacotes do tidyverse
  • readr/readxl: Importação eficiente de dados retangulares

  • tidyr: Estruturação de dados no formato “tidy” (pivot_longer, pivot_wider)

  • dplyr: Manipulação de dados com verbos intuitivos (filter, select, mutate)

  • ggplot2/gt: Visualização de dados baseada na gramática dos gráficos

  • O tidyverse implementa o princípio de “tidy data”, criando um fluxo de trabalho coeso através do operador pipe (%>% ou |>).

Integração entre os Pacotes

O grande poder do tidyverse está na integração entre seus pacotes. Exemplo: um fluxo completo que:

  1. Transforma os dados (mutate)
  2. Agrupa e resume estatísticas (group_by, summarise)
  3. Converte em formato longo (pivot_longer)
  4. Visualiza os dados (ggplot2)

Princípios do tidyverse

  • Consistência: funções com sintaxe similar.
  • Composição: código encadeado com %>% ou |>.
  • Clareza sem ambiguidade: nomes expressivos e argumentos explícitos.
  • Reprodutibilidade: fácil de entender, refatorar e auditar.

A filosofia do tidyverse está alinhada com os princípios modernos de ciência de dados transparente, auditável e reproduzível.

6.1 Dados Organizados

  • O conceito de Tidy Data (Dados Organizados) foi formalizado por Hadley Wickham.

  • Um arquivo de dados organizado possui a seguinte estrutura:

    • Cada linha representa uma observação individual
    • Cada coluna representa uma variável específica
    • Cada célula contém um valor de uma variável para uma observação específica
  • A Figura 1 ilustra o conceito de dados organizados visualmente.

Fig. 1: Dados Organizados
Benefícios de Dados Organizados
  • Adequação para Ferramentas: Formato de armazenamento de dados adequado para análise em linguagens (R/Python) e softwares de análise de dados.

  • Consistência: Estrutura uniforme para todos os conjuntos de dados

  • Facilidade para operações comuns:

    • Filtragem de observações
    • Seleção de variáveis
    • Criação de novas variáveis
    • Agregação de dados
    • Junção de múltiplas tabelas
Dados Financeiros Desorganizados Típicos

Colunas contendo valores: Nomes de colunas contendo valores de uma ou mais variáveis.

  • Ex: Colunas nomeadas com anos (2020, 2021, 2022)
| Empresa   | 2020    | 2021    | 2022    |
|-----------|---------|---------|---------|
| Empresa A | 350.000 | 425.000 | 510.000 |
| Empresa B | 780.000 | 815.000 | 840.000 |
| Empresa C | 540.000 | 490.000 | 620.000 |
Versão Organizada dos Dados Anteriores:
| Empresa   | Ano  | Valor   |
|-----------|------|---------|
| Empresa A | 2020 | 350.000 |
| Empresa A | 2021 | 425.000 |
| Empresa A | 2022 | 510.000 |
| Empresa B | 2020 | 780.000 |
| Empresa B | 2021 | 815.000 |
| Empresa B | 2022 | 840.000 |
| Empresa C | 2020 | 540.000 |
| Empresa C | 2021 | 490.000 |
| Empresa C | 2022 | 620.000 |

Características:

  • Cada variável está em uma coluna separada
  • Cada observação está em uma linha
  • Cada célula contém um valor único
Tipos de “Desorganização” Comuns em Administração

Múltiplas variáveis em uma coluna: Uma coluna contendo mais de uma variável

  • Ex: “Nome_Empresa (Ano)” combinando empresa e ano
| Nome_Empresa (Ano) | Receita       | Despesa       |
|--------------------|---------------|---------------|
| Empresa A (2020)   | R$ 350.000,00 | R$ 290.000,00 |
| Empresa A (2021)   | R$ 425.000,00 | R$ 320.000,00 |
| Empresa B (2020)   | R$ 780.000,00 | R$ 710.000,00 |
| Empresa B (2021)   | R$ 815.000,00 | R$ 735.000,00 |
  • Não se deve usar unidades (R$ no caso) em arquivos para armazenamento de dados para análise.
Versão Organizada dos Dados:
| Empresa    | Ano  | Receita  | Despesa  |
|------------|------|----------|----------|
| Empresa A  | 2020 | 350000   | 290000   |
| Empresa A  | 2021 | 425000   | 320000   |
| Empresa B  | 2020 | 780000   | 710000   |
| Empresa B  | 2021 | 815000   | 735000   |
Múltiplas variáveis em uma coluna:
  • Os números referem-se ao lucro líquido trimestral das empresas em milhões de reais:
| Empresa    | T1 2023 | T2 2023 | T3 2023 | T4 2023 |
|------------|---------|---------|---------|---------|
| TechSoft   | 25.3    | 31.7    | 28.4    | 35.2    |
| VarejoMax  | 12.8    | 15.4    | 19.3    | 22.7    |
| FinGroup   | 41.6    | 38.9    | 45.2    | 51.8    |
  • Problemas:

    • Valores de uma variável (trimestre) estão nas colunas
    • Não segue o princípio “uma coluna, uma variável”
    • Dificulta análises temporais e comparativas
Versão Organizada dos Dados:
| Empresa   | Trimestre | Ano  | Lucro_Liquido |
|-----------|-----------|------|---------------|
| TechSoft  | T1        | 2023 | 25.3          |
| TechSoft  | T2        | 2023 | 31.7          |
| TechSoft  | T3        | 2023 | 28.4          |
| TechSoft  | T4        | 2023 | 35.2          |
| VarejoMax | T1        | 2023 | 12.8          |
| VarejoMax | T2        | 2023 | 15.4          |
| VarejoMax | T3        | 2023 | 19.3          |
| VarejoMax | T4        | 2023 | 22.7          |
| FinGroup  | T1        | 2023 | 41.6          |
| FinGroup  | T2        | 2023 | 38.9          |
| FinGroup  | T3        | 2023 | 45.2          |
| FinGroup  | T4        | 2023 | 51.8          |
Tipos de “Desorganização” Comuns em Administração

Variáveis em linhas e colunas

  • Ex: Planilha de desempenho onde ROE aparece como coluna, mas Lucro Líquido e outras variáveis aparecem nas linhas
| Empresa            | ROE (%)       | Liquidez Corrente |
|--------------------|---------------|-------------------|
| Empresa XYZ        | 15,2          | 1,8               |
| Lucro Líquido      | R$ 2.500.000  | -                 |
| Patrimônio Líquido | R$ 16.400.000 | -                 |
| Ativo Circulante   | -             | R$ 3.600.000      |
| Passivo Circulante | -             | R$ 2.000.000      |
Versão Organizada dos Dados:
| Empresa    | Indicador           | Valor       |
|------------|---------------------|-------------|
| Empresa XYZ| ROE                 | 0.152       |
| Empresa XYZ| Liquidez Corrente   | 1.8         |
| Empresa XYZ| Lucro Líquido       | 2500000     |
| Empresa XYZ| Patrimônio Líquido  | 16400000    |
| Empresa XYZ| Ativo Circulante    | 3600000     |
| Empresa XYZ| Passivo Circulante  | 2000000     |
Por que a absoluta maioria dos arquivos de dados são desorganizados?
  • Por que a maioria das pessoas que trabalham na área de negócios não está familiarizada com os princípios da organização de dados para análise e utilizam planilhas eletrônicas para trabalhar com dados.

  • Planilhas de dados são frequentemente organizadas pensando em apresentar os dados ou para tornar a entrada de dados mais simples, não em um formato adequado para armazenamento e análise.

  • Isso significa que, para a maioria das análises reais, cientistas e analistas de dados dispendem muito tempo e esforço organizando e preparando dados elaborados por terceiros.

  • A primeira etapa é sempre descobrir quais são as observações e as variáveis associadas a cada observação.

Benefícios para Dissertações e Artigos Científicos

Dados organizados viabilizam e facilitam a:

  • Reprodutibilidade: Formato padronizado que outros pesquisadores podem entender e utilizar

  • Visualizações avançadas: Estrutura ideal para a criação de diversos tipos de tabelas e gráficos.

  • Análise econométrica: Adequação imediata para estudos e modelos econométricos em (regressão linear, painel, logit, probit etc.)

6.2 Planilhas Eletrônicas

Broman e Woo (2018): Riscos para Armazenamento de Dados
  • Planilhas eletrônicas têm alto risco de erros: Em 13 auditorias de planilhas reais, uma média de 88% continham erros (Broman e Woo, 2018).

  • Problemas comuns incluem:

    • Conversão automática de formatos (ex: nomes de genes interpretados como datas)

    • Armazenamento de datas de forma diferente entre sistemas operacionais

    • Cálculos incorporados que podem corromper dados originais

    • A mistura de análise, visualização e armazenamento no mesmo arquivo aumenta o risco de comprometer os dados brutos e os resultados.

  • Mas dada a ubiquidade de planilhas nas organizações, caso precise usar planilhas para armazenar dados, siga as seguintes boas práticas:

Recomendações práticas para organizar dados em planilhas.
  • Artigo de Broman e Woo (2018)

  • Crie planilhas organizadas (uma linha = uma observação, uma coluna = uma variável, uma célula = um valor)

  • Seja consistente e escolha bons nomes para as variáveis:

    • use snake_case ou CamelCase
    • Lucro Líquido (R$) 😱
    • lucro_liquido ou LucroLiquido 😃
    • NUNCA use acentos, caracteres especiais e espaços vaziso para nomes ou valores.
  • Escreva datas conforme a Norma ISO 8601:

    • YYYY-MM-DD, exemplo: 2025-05-07
  • Sem células vazias: use hífen (-) e no caso de usar R, use NA

  • Crie um dicionário dos dados

  • NUNCA faça cálculos na planilha dos dados originais/brutos

  • NUNCA use unidades de medida (R$), cor ou realce como um dado.

    • R$ 50.000,00 😱
    • 50000 😃
    • 10 % 😱
    • O.1 😃
  • Faça backups

  • Use validação dos dados para evitar erros

  • Salve os dados em arquivos de texto simples (.csv):

    • todas as linguagens (R/Python) e softwares de análises de dados reconhecem facilmente esse formato.
Pacote tidyr

Na próxima seção, vamos aprender sobre como o pacote tidyr do tidyverse pode ser usado para tornar alguns tipos de dados desorganizados em dados organizados para análise.

7 Introdução ao Pacote tidyr

O pacote tidyr no ecossistema tidyverse
  • O tidyr é um pacote do tidyverse para organizar dados desorganizados

  • Seu nome vem de “tidy” (organizado) + “r” (R)

  • Foi criado para facilitar a transformação de dados desorganizados em dados organizados (tidy data) para análise

  • É muito útil para a preparação de dados na fase 3 do CRISP-DM (Preparação dos Dados)

  • Permite que dados em formatos comuns de planilhas e relatórios sejam transformados em formatos adequados para análise e visualização

A Principal função do pacote tidyr para nós
  • pivot_longer(): Converte dados do formato amplo (onde valores de uma ou mais variáveis são espalhadas por colunas) em um formato longo (onde cada variável está em uma única coluna).

    • Útil quando você precisa de de dados para análise ou visualização

    • Ex: Transformar colunas de trimestres (Q1, Q2, Q3, Q4) em uma única coluna “trimestre”

  • Iremos estudar somente a função pivot_longer(), porque o foco deste módulo é a preparação de dados para análise.

  • Mas há diversas outras funções úteis para a organização de dados:

7.0.1 Quando usar o tidyr?

Situações comuns em Administração
  • Quando você tem planilhas financeiras com colunas para diferentes períodos (meses, trimestres, anos)

  • Quando você recebe planilhas Excel organizadas para visualização humana, mas não para análise de dados.

  • Quando precisa combinar dados de diferentes fontes que estão em formatos incompatíveis.

  • Quando precisa preparar dados para visualizações específicas com ggplot2 (gráficos de linhas, facetas, etc.)

  • Quando realiza análises temporais e precisa converter entre formatos de data/hora.

7.0.2 A Função tidyr::pivot_longer

Ao final desta seção, você será capaz de:
  • Aplicar a função pivot_longer() com seus parâmetros essenciais: cols, names_to e values_to

  • Organizar/Transformar dados complexos extraindo múltiplas informações de colunas

  • Integrar pivot_longer() em pipelines de análise com dplyr

  • Implementar soluções para casos reais de análise de dados administrativos

Transformando dados de formato amplo para longo
  • A função pivot_longer() converte dados do formato amplo (wide) para o formato longo (long)

  • É muito útil quando as colunas contêm valores em vez de variáveis

  • Geralmente, é o primeiro passo para transformar planilhas de negócios em dados organizados para análise (tidy data)

  • A Figura 2 ilustra o uso desta função

Fig. 2: Aplicando a função pivot_longer()

7.0.3 Sintaxe da função pivot_longer()

Como usar pivot_longer() na prática
# Formato básico
dados %>%
  pivot_longer(
    cols = "valores_de_uma_nova_coluna",
    names_to = "nome_nova_coluna",
    values_to = "nome_outra_nova_coluna"
  )
  • valores_de_uma_nova_coluna: as colunas que contêm valores de uma variável e serão transformadas.

  • nome_nova_coluna: nome da nova coluna/variável que conterá os nomes das colunas originais.

  • nome_outra_nova_coluna: nome da nova coluna/variável que conterá os valores originais.

7.0.4 Função pivot_longer

Descrição
Característica pivot_longer()
Transforma Colunas → Linhas
Formato resultante Longo (mais linhas)
Quando usar Para análise e visualização
Exemplo típico Transformar colunas de anos em uma variável “ano”

7.0.5 A Função tribble()

Descrição

A função tribble() (abreviação de “transposed tibble”) é uma forma elegante de criar pequenas tibbles/data frames para exemplos ou testes:

# Criando uma data frame com tribble() - "tibble transposta"
produtos <- tribble(
  ~codigo, ~produto, ~preco, # Nomes das colunas começam com ~
  "A123", "Notebook", 3500, # Cada linha é um registro
  "B456", "Smartphone", 1800, # Os valores são separados por vírgulas
  "C789", "Monitor", 950 # A formatação facilita a leitura
)

# Visualizando a data frame criada
produtos
# A tibble: 3 × 3
  codigo produto    preco
  <chr>  <chr>      <dbl>
1 A123   Notebook    3500
2 B456   Smartphone  1800
3 C789   Monitor      950

Vantagens da função tribble():

  • Layout Visual: Cada linha do código corresponde a uma linha da data frame, tornando o código mais legível

  • Especificação direta: Os nomes das colunas são definidos com ~ (til)

  • Flexibilidade de tipos: Cada coluna pode conter diferentes tipos de dados

  • Ideal para exemplos: Perfeita para criar pequenas data frames para demonstrações ou testes.

Esta função faz parte do pacote tibble, que é carregado automaticamente quando você carrega o tidyverse.

7.0.6 Exemplo Básico de pivot_longer()

Dados de receita trimestral (formato amplo/wide)
# Criando a data frame de exemplo
receitas <- tribble(
  ~produto, ~T1, ~T2, ~T3, ~T4,
  "Produto A", 50000, 55000, 60000, 65000,
  "Produto B", 30000, 32000, 35000, 37000,
  "Produto C", 20000, 22000, 25000, 27000
)

# Visualizando a data frame original (formato amplo/wide)
receitas
# A tibble: 3 × 5
  produto      T1    T2    T3    T4
  <chr>     <dbl> <dbl> <dbl> <dbl>
1 Produto A 50000 55000 60000 65000
2 Produto B 30000 32000 35000 37000
3 Produto C 20000 22000 25000 27000

Este formato é para apresentação, não para armazenamento e análise.

Transformando para o formato longo
# Transformando para o formato longo usando pivot_longer
receitas_longas <- receitas %>%
  pivot_longer(
    cols = c("T1", "T2", "T3", "T4"), # colunas que serão valores da nova coluna
    names_to = "trimestre", # nome da nova coluna
    values_to = "receita" # nome de outra nova coluna
  )

# Visualizando o resultado (formato longo/long)
receitas_longas
# A tibble: 12 × 3
   produto   trimestre receita
   <chr>     <chr>       <dbl>
 1 Produto A T1          50000
 2 Produto A T2          55000
 3 Produto A T3          60000
 4 Produto A T4          65000
 5 Produto B T1          30000
 6 Produto B T2          32000
 7 Produto B T3          35000
 8 Produto B T4          37000
 9 Produto C T1          20000
10 Produto C T2          22000
11 Produto C T3          25000
12 Produto C T4          27000

Agora os dados estão organizados:

  • Cada linha é uma observação (um produto em um trimestre)
  • Cada coluna é uma variável (produto, trimestre, receita)
  • Cada célula contém um único valor

7.0.7 Exemplo Intermediário: Várias Colunas

Dados de desempenho financeiro
# Criando a data frame com múltiplas métricas por trimestre
desempenho <- tribble(
  ~empresa, ~receita_T1, ~receita_T2, ~despesa_T1, ~despesa_T2,
  "Empresa A", 150000, 175000, 120000, 130000,
  "Empresa B", 250000, 270000, 200000, 220000,
  "Empresa C", 100000, 115000, 80000, 95000
)

# Visualizando a data frame original
desempenho
# A tibble: 3 × 5
  empresa   receita_T1 receita_T2 despesa_T1 despesa_T2
  <chr>          <dbl>      <dbl>      <dbl>      <dbl>
1 Empresa A     150000     175000     120000     130000
2 Empresa B     250000     270000     200000     220000
3 Empresa C     100000     115000      80000      95000

Este formato é ainda mais desorganizado, pois mistura três variáveis (receita, despesa e trimestre) nos nomes das colunas.

Transformando para o formato longo com dois níveis
# Transformando para o formato longo usando pivot_longer com nomes separados
desempenho_longo <- desempenho %>%
  pivot_longer(
    cols = -empresa, # todas as colunas exceto "empresa"
    names_to = c("indicador", "trimestre"), # nomes das duas novas colunas
    names_sep = "_", # separador nos nomes das colunas
    values_to = "valor" # nome de nova coluna para receber os valores
  )

# Visualizando o resultado
desempenho_longo
# A tibble: 12 × 4
   empresa   indicador trimestre  valor
   <chr>     <chr>     <chr>      <dbl>
 1 Empresa A receita   T1        150000
 2 Empresa A receita   T2        175000
 3 Empresa A despesa   T1        120000
 4 Empresa A despesa   T2        130000
 5 Empresa B receita   T1        250000
 6 Empresa B receita   T2        270000
 7 Empresa B despesa   T1        200000
 8 Empresa B despesa   T2        220000
 9 Empresa C receita   T1        100000
10 Empresa C receita   T2        115000
11 Empresa C despesa   T1         80000
12 Empresa C despesa   T2         95000

Observação importante:

  • Os nomes das colunas originais (receita_T1, receita_T2, etc.) são divididos pelo separador “_” em exatamente duas partes.

  • A primeira parte (“receita” ou “despesa”) vai para a coluna “indicador” e a segunda parte (“T1” ou “T2”) vai para a coluna “trimestre”.

  • Este é um padrão comum em dados financeiros: quando os nomes de colunas seguem um formato consistente com separadores, podemos extrair as informações contidas neles para criar novas variáveis.

7.0.8 Exemplo Avançado

Indicadores financeiros por trimestre
# Exemplo mais gerenciável para slides
receita_trimestral <- tribble(
  ~empresa, ~`2022_T1_Receita`, ~`2022_T2_Receita`, ~`2023_T1_Receita`, ~`2023_T2_Receita`,
  "ABC Ltda", 1200000, 1350000, 1500000, 1620000,
  "XYZ S.A.", 2500000, 2700000, 2900000, 3100000
)

# Visualizando a data frame original
receita_trimestral
# A tibble: 2 × 5
  empresa  `2022_T1_Receita` `2022_T2_Receita` `2023_T1_Receita`
  <chr>                <dbl>             <dbl>             <dbl>
1 ABC Ltda           1200000           1350000           1500000
2 XYZ S.A.           2500000           2700000           2900000
# ℹ 1 more variable: `2023_T2_Receita` <dbl>
  • Temos informações de ano e trimestre nos nomes das colunas
Organizando dados financeiros complexos
# Transformando para o formato longo usando pivot_longer com três níveis
receita_trimestral_organizada <- receita_trimestral %>%
  pivot_longer(
    cols = -empresa, # todas as colunas exceto "empresa"
    names_to = c("ano", "trimestre"), # nomes de duas novas colunas
    names_sep = "_", # separador nos nomes das colunas
    values_to = "receita" # nome de nova coluna para receber os valores da receita
  )

# Visualizando o resultado
receita_trimestral_organizada
# A tibble: 8 × 4
  empresa  ano   trimestre receita
  <chr>    <chr> <chr>       <dbl>
1 ABC Ltda 2022  T1        1200000
2 ABC Ltda 2022  T2        1350000
3 ABC Ltda 2023  T1        1500000
4 ABC Ltda 2023  T2        1620000
5 XYZ S.A. 2022  T1        2500000
6 XYZ S.A. 2022  T2        2700000
7 XYZ S.A. 2023  T1        2900000
8 XYZ S.A. 2023  T2        3100000

7.0.9 Resumo: Função pivot_longer()

O que você precisa lembrar
  1. Finalidade: Transformar dados do formato amplo (wide) para o formato longo (long), organizando-os conforme o princípio tidy data

  2. Sintaxe básica:

dados %>%
  pivot_longer(
    cols = colunas_a_transformar,
    names_to = "nome_nova_coluna_para_nomes",
    values_to = "nome_nova_coluna_para_valores"
  )
  1. Parâmetros principais:
  • cols: Quais colunas serão transformadas em pares nome-valor
  • names_to: Nome da nova coluna que receberá os nomes das colunas originais
  • values_to: Nome da nova coluna que receberá os valores


4. Caso avançado:

  • Quando os nomes de colunas contêm múltiplas informações, use:

    • names_to = c("variavel1", "variavel2", ...)
    • names_sep = "_" (ou outro separador presente nos nomes)


5. Benefícios:

  • Padroniza o formato de dados conforme princípios da ciência de dados
  • Facilita análises com dplyr (group_by, summarize, etc.)
  • Prepara dados para visualizações eficientes

7.0.10 Dicas para Trabalhar com tidyr

Recomendações práticas
  1. Identifique as variáveis: Antes de transformar, identifique claramente quais são as observações e variáveis reais nos seus dados

  2. Comece com subconjuntos: Para dados complexos, comece testando com um pequeno subconjunto de dados

  3. Use nomes descritivos: Escolha bons nomes para as novas colunas criadas por pivot_longer()

  4. Combine com dplyr: As transformações com tidyr geralmente são seguidas por operações com dplyr para análise

  5. Verifique os resultados: Sempre confira se os dados transformados mantêm as mesmas informações dos dados originais

7.0.11 Resumo: Pacote tidyr

O que você precisa lembrar
  1. O que faz: O pacote tidyr transforma dados entre os formatos amplo (wide) e longo (long)

  2. Principal função:

    • pivot_longer(): Converte de amplo (wide) para longo (long) (colunas para linhas)
  3. Quando usar:

    • Use pivot_longer() quando colunas contiverem valores em vez de variáveis
  4. Importância na análise de dados:

    • É essencial para a preparação de dados (fase 3 do CRISP-DM)

    • Permite transformar dados comuns de negócios em formatos adequados para análise

    • Facilita a aplicação de funções do dplyr e criação de visualizações

  5. Lembre-se sempre:

    • Dados organizados (tidy) têm uma variável por coluna, uma observação por linha.

8 Introdução ao Pacote dplyr

O pacote dplyr no ecossistema tidyverse
  • O dplyr é um dos pacotes principais do tidyverse, criado por Hadley Wickham

  • Seu nome vem de “data plier” (alicate para dados) - uma ferramenta para manipular dados

  • Foi projetado seguindo a filosofia “tidy data” (dados organizados) - cada variável é uma coluna, cada observação é uma linha

  • É escrito em C++ para performance otimizada

  • Permite manipulação de dados de forma consistente, clara e encadeada

O dplyr no Ecossistema R
  • O pacote dplyr é parte do tidyverse

  • Enquanto os pacotes readr e readxl ajudam na importação de dados, o dplyr é especializado na manipulação de dados

  • O dplyr foi otimizado para manipular sobre dados organizados, longos ou tidy data

  • O dplyr trabalha com uma estrutura de dados de R que já conhecemos: data frames/tibbles

  • As funções do dplyr foram projetadas para serem usadas com o operador pipe (%>%), que já vimos brevemente no relatório Junglivet

O dplyr como uma “linha de produção”

Imagine o processo de análise de dados como uma linha de produção:

  • Os dados brutos são sua “matéria-prima”

  • Cada função do dplyr é uma “estação de trabalho” que realiza uma operação específica:

    • filter() seleciona apenas os materiais que atendem a certos critérios
    • select() separa apenas as partes que você precisa
    • mutate() transforma ou cria novos componentes
    • group_by() + summarize() agrupam e calculam estatísticas
    • arrange() organiza o resultado final
  • O operador pipe (%>%) é a “esteira” que move os dados de uma estação para outra

Operações Comuns em Análise de Dados
  • Muitas vezes precisamos filtrar somente certas linhas (observações ) de uma data frame.

  • Muitas vezes precisamos selecionar somente certas colunas (variáveis) de uma data frame.

  • Muitas vezes precisamos agrupar os dados por uma determinada(s) variável(s) categórica.

  • Muitas vezes precisamos calcular estatísticas descritivas para esses subconjuntos de dados (função summarize).

8.0.1 Por que usar o dplyr?

  • Exemplo 1: Usando R base
# pib per capita médio dos países do continente americano
mean(gapminder$gdpPercap[gapminder$continent == "Americas"])
[1] 7136.11
  • Exemplo 1: Usando o pacote dplyr
# pib per capita médio dos países do continente americano
gapminder %>%
  filter(continent == "Americas") %>%
  summarize(mean(gdpPercap))
# A tibble: 1 × 1
  `mean(gdpPercap)`
              <dbl>
1             7136.
  • Exemplo 2: R base (aninhado)
# Calcular a média de PIB per capita para 
# países asiáticos com população > 50 milhões 
# em 2007
mean(gapminder$gdpPercap[
  gapminder$continent == "Asia" & 
  gapminder$pop > 50000000 & 
  gapminder$year == 2007
])
[1] 7130.141
  • Difícil de ler e entender

  • Propenso a erros

  • Difícil de modificar

  • Exemplo 2: Com dplyr e o operador pipe

# O mesmo cálculo com dplyr
gapminder %>%
  filter(
    continent == "Asia",
    pop > 50000000,
    year == 2007
  ) %>%
  summarize(mean(gdpPercap))
# A tibble: 1 × 1
  `mean(gdpPercap)`
              <dbl>
1             7130.
  • Leitura sequencial, mais natural
  • Cada etapa claramente separada
  • Fácil de modificar ou expandir

8.0.2 Comparando Abordagens

Vantagens e Desvantagens

Base R: Funções aninhadas

  • Vantagens: Não requer pacotes adicionais, disponível em qualquer instalação do R

  • Desvantagens:

    • Código difícil de ler com funções aninhadas
    • Difícil de depurar quando há erros
    • Funções com sintaxes inconsistentes

dplyr: Gramática da manipulação de dados

  • Vantagens:

    • Código mais legível e expressivo
    • Funções com nomes intuitivos e consistentes
    • Ideal para análises sequenciais com pipes
  • Desvantagens:

    • Requer aprender uma nova sintaxe (para usuários experientes)
    • Dependência de pacotes externos
    • Algumas operações podem ser mais lentas que o R base em casos específicos

8.0.3 Fluxo de trabalho com tidyvese

Gramática da manipulação de dados

O fluxo típico de uma análise de dados com tidyverse segue este padrão:

  1. Importar dados (com pacotes here, readr, readxl,…)
  2. Organizar dados para análise (pacote tidyr)
  3. Unir arquivos/tabelas se necessário (funções para joins)
  4. Filtrar observações (função filter)
  5. Selecionar variáveis (função select)
  6. Transformar dados (função mutate)
  7. Agrupar dados (função group_by)
  8. Resumir informações (função summarize)
  9. Ordenar resultados (função arrange)

8.0.4 Um Pipeline de Análise com dplyr

Informações sobre expectativa de vida por continente
# Um pipeline de análise com dplyr
relatorio_expectativa <- gapminder %>%
  # Filtra apenas os dados de 2007
  filter(year == 2007) %>%
  # Agrupa por continente
  group_by(continent) %>%
  # Calcula estatísticas resumidas
  summarize(
    expectativa_media = mean(lifeExp),
    expectativa_minima = min(lifeExp),
    expectativa_maxima = max(lifeExp),
    num_paises = n()
  ) %>%
  # Ordena do maior para o menor
  arrange(desc(expectativa_media))

# Visualiza o resultado final
relatorio_expectativa
# A tibble: 5 × 5
  continent expectativa_media expectativa_minima expectativa_maxima num_paises
  <fct>                 <dbl>              <dbl>              <dbl>      <int>
1 Oceania                80.7               80.2               81.2          2
2 Europe                 77.6               71.8               81.8         30
3 Americas               73.6               60.9               80.7         25
4 Asia                   70.7               43.8               82.6         33
5 Africa                 54.8               39.6               76.4         52

Este exemplo demonstra como um conjunto de funções do dplyr pode ser combinado para transformar dados brutos organizados em um relatório informativo com apenas algumas linhas de código.

Pacote dplyr: Vantagens

O pacote dplyr fornece uma série de funções muito úteis para manipular data frames de uma maneira que:

  • reduz a probabilidade de cometer erros
  • economiza digitação
  • o código é mais legível e compreensível
Objetivos de Aprendizagem

Vamos aprender 5 das funções mais usadas do pacote dplyr,

Função Descrição
dplyr::filter() para filtrar linhas (observações)
dplyr::select() para selecionar colunas (variáveis )
dplyr::mutate() para criar novas variáveis
dplyr::group_by() para operações “por grupo”
dplyr::summarize() para calcular estatísticas
dplyr::arrange() para ordenar resultados

Além disso, veremos como como usar o operador pipe (%>%) para combiná-las.

8.0.5 Boas Práticas com dplyr

Recomendações para código eficiente e legível
  1. Indentação consistente:

    • Um nível de identação para cada função
    • Parâmetros adicionais alinhados
  2. Nomeie seu código:

    • Use nomes descritivos para variáveis intermediárias e finais
    • Ex: dados_filtrados, relatorio_vendas_por_regiao
  3. Comente seu código:

    • Explique o “por quê”, não apenas o “o quê”
    • Útil para você mesmo no futuro e para colegas
  4. Dividir análises complexas em etapas:

    • Para análises muito complexas, divida em objetos intermediários
    • Facilita a depuração e compreensão
  5. Consistência de estilo:

    • Seja consistente com o estilo de nomeação (snake_case ou CamelCase)
    • Seja consistente com o uso de aspas (simples ou duplas)

8.0.6 Pacote gapminder - Dados

Descrição
  • O pacote gapminder da linguagem R contém uma data frame também chamada gapminder.

  • A df gapminder fornece informações detalhadas sobre indicadores socioeconômicos reais de vários países ao longo do tempo.

  • Este conjunto de dados é muito utilizado no ensino da linguagem R e de métodos estatísticos.

  • Vamos utilizar a df gapminder para ilustrar as funções do pacote dplyr.

  • Para acessar os dados gapminder, basta instalar e carregar o pacote gapminder:

# carrega os pacotes
library(tidyverse)
library(gapminder)

8.0.7 Data Frame gapminder

Fase 1 (CRISP-DM): Entendimento dos Dados

Para obter uma visão geral da estrutura da df gapminder, podemos usar a função glimpse do pacote dplyr:

# visualizando a estrutura dos dados
dplyr::glimpse(gapminder)
Rows: 1,704
Columns: 6
$ country   <fct> "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", …
$ continent <fct> Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, …
$ year      <int> 1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, …
$ lifeExp   <dbl> 28.801, 30.332, 31.997, 34.020, 36.088, 38.438, 39.854, 40.8…
$ pop       <int> 8425333, 9240934, 10267083, 11537966, 13079460, 14880372, 12…
$ gdpPercap <dbl> 779.4453, 820.8530, 853.1007, 836.1971, 739.9811, 786.1134, …

Podemos também inspecionar as primeiras 6 linhas da data frame com a função head:

head(gapminder)
# A tibble: 6 × 6
  country     continent  year lifeExp      pop gdpPercap
  <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
1 Afghanistan Asia       1952    28.8  8425333      779.
2 Afghanistan Asia       1957    30.3  9240934      821.
3 Afghanistan Asia       1962    32.0 10267083      853.
4 Afghanistan Asia       1967    34.0 11537966      836.
5 Afghanistan Asia       1972    36.1 13079460      740.
6 Afghanistan Asia       1977    38.4 14880372      786.

8.0.8 Boa Prática

Dicionário dos dados

A data frame gapminder contida no pacote de mesmo nome, possui 1704 linhas (observações) e 6 colunas (variáveis).

Variável Classe/Tipo Descrição
country factor Nome do país (142 níveis/países)
continent factor Continente ao qual o país pertence (5 níveis/continentes)
year integer Ano da observação (1952 a 2007 em incrementos de 5 anos)
lifeExp double Expectativa de vida ao nascer, em anos
pop integer População total do país
gdpPercap double PIB per capita em US$, ajustado pela inflação

8.1 Função select()

8.1.1 O que é a função select()?

Selecionando variáveis (colunas) de uma data frame
  • A função select() permite escolher quais variáveis (colunas) você quer manter ou remover de uma data frame

  • Enquanto select() trabalha com colunas (variáveis), filter() trabalha com linhas (observações),

  • É essencial para simplificar seus dados, focando apenas nas variáveis relevantes para sua análise

8.1.2 Sintaxe da função select()

Sintaxe básica
# Estrutura básica
select(df, var1, var2, var3)

# Com operador pipe
df %>% select(var1, var2, var3)
  • df: A data frame da qual você quer selecionar variáveis
  • var1, var2, var3: Nomes das variáveis que você quer manter
  • Todas as variáveis não listadas serão removidas do resultado

8.1.3 Exemplo: Análise Financeira Simplificada

Cenário: Análise financeira de países

Imagine que você é um analista financeiro internacional e precisa preparar um relatório sobre PIB:

# Seleciona apenas as variáveis relevantes para análise financeira
dados_financeiros <- gapminder %>%
  select(country, year, gdpPercap)

# Visualiza as primeiras linhas do resultado
head(dados_financeiros)
# A tibble: 6 × 3
  country      year gdpPercap
  <fct>       <int>     <dbl>
1 Afghanistan  1952      779.
2 Afghanistan  1957      821.
3 Afghanistan  1962      853.
4 Afghanistan  1967      836.
5 Afghanistan  1972      740.
6 Afghanistan  1977      786.

Interpretação: Este código seria equivalente a extrair apenas os dados financeiros relevantes (país, ano e PIB per capita) de uma grande base de dados para uma análise específica de desempenho econômico.

8.1.4 Técnicas de Seleção Avançadas

Diversas formas de selecionar variáveis
# Selecionar variáveis por inclusão
gapminder %>% select(country, year, gdpPercap)

# Selecionar variáveis por exclusão (com sinal de menos)
gapminder %>% select(-continent, -lifeExp)

# Selecionar variáveis em sequência
gapminder %>% select(country:pop)

# Selecionar variáveis que começam com determinado texto
gapminder %>% select(starts_with("c"))

# Selecionar variáveis que terminam com determinado texto
gapminder %>% select(ends_with("p"))

# Selecionar variáveis que contêm determinado texto
gapminder %>% select(contains("exp"))
Aplicações práticas em negócios

Estas técnicas são muito úteis quando você trabalha com:

  • Grandes conjuntos de dados com dezenas ou centenas de variáveis
  • Planilhas de dados financeiros onde precisa focar em determinadas métricas
  • Relatórios onde precisa apresentar apenas informações específicas

8.1.5 Erros Comuns e Como Evitá-los

Os erros mais comuns com select()
Erro Errado Correto
Nomes de variáveis com aspas select(gapminder, "country") select(gapminder, country)
Tentar condições como em filter select(gapminder, gdpPercap > 1000) Use filter() para isso, não select()
Não salvar o resultado gapminder %>% select(country, year) dados_novos <- gapminder %>% select(country, year)
Remover variáveis necessárias select(country) e depois tentar usar continent Verifique se manteve todas as variáveis necessárias
Dica importante:

Lembre-se: select() é para escolher colunas (variáveis) e filter() é para escolher linhas (observações)!

8.1.6 Exemplo: Salvando o resultado

Seleção por Exclusão
  • Se quisermos remover apenas a variável continent, podemos usar a sintáxe abaixo e salvar o resultado em outro objeto:
variaveis_selecionadas <- select(gapminder, -continent)
variaveis_selecionadas
# A tibble: 1,704 × 5
   country      year lifeExp      pop gdpPercap
   <fct>       <int>   <dbl>    <int>     <dbl>
 1 Afghanistan  1952    28.8  8425333      779.
 2 Afghanistan  1957    30.3  9240934      821.
 3 Afghanistan  1962    32.0 10267083      853.
 4 Afghanistan  1967    34.0 11537966      836.
 5 Afghanistan  1972    36.1 13079460      740.
 6 Afghanistan  1977    38.4 14880372      786.
 7 Afghanistan  1982    39.9 12881816      978.
 8 Afghanistan  1987    40.8 13867957      852.
 9 Afghanistan  1992    41.7 16317921      649.
10 Afghanistan  1997    41.8 22227415      635.
# ℹ 1,694 more rows

8.1.7 Pacote dplyr e o operador pipe ( |> ou %>%)

Combinação de Operações com |> ou %>%
  • Nos slides anteriores, usamos a sintáxe ‘normal’ da linguagem R.

  • Mas o ponto forte do dplyr está na combinação de várias funções usando o operador pipe %>%.

  • Vamos analisar a gramática do uso de funções do dplyr combinadas com o operador %>%.

  • Atalho para inserir o operador pipe: Ctrl + shift + M

Significado conceitual do pipe %>%
  • O operador pipe pode ser lido como “então” ou “em seguida”

  • Fluxo da esquerda para a direita, similar à leitura natural

  • Transforma:

funcao(dados, arg1, arg2)

em

dados %>% funcao(arg1, arg2)

Analogia

Uma linha de montagem onde cada função faz uma operação nos dados

gapminder %>% # Pegue os dados gapminder, então...
  filter(year == 2007) %>% # Filtre para apenas o ano 2007, então...
  group_by(continent) %>% # Agrupe por continente, então...
  summarize( # Calcule resumos:
    mean(lifeExp), # expectativa de vida média
    sum(pop) # população total 
  )
# A tibble: 5 × 3
  continent `mean(lifeExp)` `sum(pop)`
  <fct>               <dbl>      <dbl>
1 Africa               54.8  929539692
2 Americas             73.6  898871184
3 Asia                 70.7 3811953827
4 Europe               77.6  586098529
5 Oceania              80.7   24549947
Nomeie os resumos calculados com summarize
gapminder %>% # Pegue os dados gapminder, então...
  filter(year == 2007) %>% # Filtre para apenas o ano 2007, então...
  group_by(continent) %>% # Agrupe por continente, então...
  summarize( # Calcule resumos:
    exp_vida_media = mean(lifeExp), # expectativa de vida média
    populacao_total = sum(pop) # população total
  )
# A tibble: 5 × 3
  continent exp_vida_media populacao_total
  <fct>              <dbl>           <dbl>
1 Africa              54.8       929539692
2 Americas            73.6       898871184
3 Asia                70.7      3811953827
4 Europe              77.6       586098529
5 Oceania             80.7        24549947

8.1.8 Função select() e o Operador Pipe

Selecionando Variáveis com o Pipe
variaveis_selecionadas <- gapminder %>%
  dplyr::select(year, country, gdpPercap)

Vamos entender o código:

  1. Primeiro invocamos a df gapminder e a passamos, usando o operador pipe %>%, para a próxima etapa, que é a função select().

  2. Neste caso, não especificamos qual df usamos na função select(), porque que ela obtém essa informação do pipe anterior.

  3. Salvamos o resultado no objeto variaveis_selecionadas

8.1.9 Resumo: Função select()

O que você precisa lembrar
  1. Para que serve: Selecionar apenas as colunas (variáveis) que você deseja manter ou remover

  2. Sintaxe básica:

dados %>% select(var1, var2, var3)  # Mantém apenas var1, var2 e var3
dados %>% select(-var4, -var5)      # Remove var4 e var5, mantém o resto
  1. Técnicas úteis:
    • Seleção por inclusão: select(país, ano, vendas)
    • Seleção po exclusão: select(-observações, -notas)
    • Seleção por padrão de texto: select(starts_with("venda"))
  2. Lembre-se sempre:
    • select() trabalha com COLUNAS
    • filter() trabalha com LINHAS
    • Sempre salve o resultado em um novo objeto!
novo_df <- dados %>% select(...)

8.2 Função filter()

8.2.1 O que é a função filter()?

Filtrando observações (linhas) de uma data frame
  • A função filter() permite filtrar subconjuntos de observações (linhas) que atendem determinadas condições ou critérios.

  • É uma das funções mais utilizadas na análise de dados para criar subconjuntos específicos dos dados

  • Pense nela como um “filtro” que deixa passar apenas as observações que atendem aos critérios que você definir

Neste caso, duas linhas atendem às condições

8.2.2 O que é a função filter()?

Filtrando observações (linhas) de uma data frame
  • Imagine que você tem uma planilha de vendas e quer analisar apenas as vendas:

    • de um produto específico
    • acima de determinado valor
    • em uma região específica
    • em um período específico
  • A função filter() permite fazer essa filtragem de forma rápida e precisa

8.2.3 Sintaxe da função filter()

Sintaxe básica
# Estrutura básica
filter(df, condição)

# Com operador pipe
df %>% filter(condição)
  • df: A data frame a ser filtrada
  • condição: Expressão lógica que retorna TRUE/FALSE para cada linha
  • Somente as linhas que resultam em TRUE são mantidas no resultado

8.2.4 Operadores para construir condições

Operadores na linguagem dos negócios
Operador Exemplo em Linguagem Natural Código em R
== Apenas os países europeus continent == “Europe”
!= Todos, exceto os países europeus continent != “Europe”
> Países com PIB per capita maior que 10.000 gdpPercap > 10000
< Países com menos de 1 milhão de habitantes pop < 1000000
>= Países a partir do ano 2000 year >= 2000
& Países europeus a partir de 2000 continent == “Europe” & year >= 2000
| Países da Europa ou da Ásia continent == “Europe” | continent == “Asia”
Dicas
  • Use == para igualdade (lembre-se: dois sinais de igual, não apenas um)
  • Use & para “E” (quero este critério E aquele também)
  • Use | para “OU” (quero este critério OU aquele)

8.2.5 Exemplo básico

Cenário: Análise de vendas por continente

Imagine que a data frame gapminder representa dados de filiais de uma empresa multinacional:

# Filtra apenas países das Américas
# como se fossem filiais da região Américas

filiais_americas <- gapminder %>%
  filter(continent == "Americas")

# Visualiza as primeiras 6 linhas do resultado
head(filiais_americas)
# A tibble: 6 × 6
  country   continent  year lifeExp      pop gdpPercap
  <fct>     <fct>     <int>   <dbl>    <int>     <dbl>
1 Argentina Americas   1952    62.5 17876956     5911.
2 Argentina Americas   1957    64.4 19610538     6857.
3 Argentina Americas   1962    65.1 21283783     7133.
4 Argentina Americas   1967    65.6 22934225     8053.
5 Argentina Americas   1972    67.1 24779799     9443.
6 Argentina Americas   1977    68.5 26983828    10079.

Interpretação: Este filtro seria equivalente a selecionar apenas dados de filiais localizadas nas Américas para uma análise regional de desempenho.

8.2.6 Pensando como um Analista de Negócios

Perguntas de negócios traduzidas para filter()
Pergunta de Negócio Código com filter()
Quais países tiveram PIB per capita acima de $20.000 em 2007? filter(year == 2007 & gdpPercap > 20000)
Quais países da Ásia tiveram expectativa de vida acima de 75 anos? filter(continent == "Asia" & lifeExp > 75)
Quais países tiveram população superior a 100 milhões em 2007? filter(year == 2007 & pop > 100000000)
Quais países não são da Europa nem da América? filter(continent != "Europe" & continent != "Americas")

Dica: Comece sempre pensando na pergunta de negócio, depois traduza para o código

8.2.7 Múltiplas condições com filter()

Combinando condições

Há duas maneiras principais de combinar condições:

# Método 1: Usando o operador & (E lógico) - equivalente ao método 1
europeus_2007_alt <- gapminder %>%
  filter(continent == "Europe" & year == 2007)

# Método 2: Usando o operador | (OU lógico)
europa_ou_asia <- gapminder %>%
  filter(continent == "Europe" | continent == "Asia")

Dica importante:

  • Com & (“E”) ambas as condições precisam ser TRUE para que a linha seja mantida

  • Com | (“OU”), apenas uma das condições precisa ser TRUE

8.2.8 Filtrando com operadores relacionais

Exemplos com diferentes operadores
# Países com alta expectativa de vida (maior que 80 anos)
alta_exp_vida <- gapminder %>%
  filter(lifeExp > 80)

# Países com PIB per capita abaixo de 500 dólares
baixo_pib <- gapminder %>%
  filter(gdpPercap < 500)

# Anos diferentes de 2002
nao_2002 <- gapminder %>%
  filter(year != 2002)

Utilize operadores relacionais para:

  • Encontrar valores acima/abaixo de limites importantes
  • Excluir períodos ou categorias específicas
  • Identificar casos extremos ou outliers

8.2.9 Combinando filter() com outras funções

A importância da ordem das operações
# Países europeus em 2007, mostrando apenas país e expectativa de vida
europeus_lifeExp_2007 <- gapminder %>%
  filter(continent == "Europe" & year == 2007) %>%
  select(country, lifeExp)

# Ordenando o resultado por expectativa de vida (decrescente)
europeus_lifeExp_2007_ordenado <- gapminder %>%
  filter(continent == "Europe" & year == 2007) %>%
  select(country, lifeExp) %>%
  arrange(desc(lifeExp))

head(europeus_lifeExp_2007_ordenado)
# A tibble: 6 × 2
  country     lifeExp
  <fct>         <dbl>
1 Iceland        81.8
2 Switzerland    81.7
3 Spain          80.9
4 Sweden         80.9
5 France         80.7
6 Italy          80.5

Ordem correta das operações:

  1. Comece com filter()
  2. Use select() depois de filter
  3. Se inverter a ordem, a função filter() pode falhar se você removeu colunas necessárias

Lembre-se: primeiro filter(), depois select()!

8.2.10 Erros Comuns e Como Evitá-los

Os 4 erros mais comuns com filter()
Erro Errado Correto
Usar = em vez de == filter(continent = "Europe") filter(continent == "Europe")
Esquecer as aspas em nomes filter(continent == Europe) filter(continent == "Europe")
Não salvar o resultado gapminder %>% filter(year == 2007) dados_2007 <- gapminder %>% filter(year == 2007)

8.2.11 Exemplo Completo Comum

Países europeus com alta expectativa de vida em 2007?
# Países europeus com expectativa de vida acima de 78 anos em 2007
resultado_final <- gapminder %>%
  # Filtrar por continente, ano e expectativa de vida
  filter(continent == "Europe" & year == 2007 & lifeExp > 78) %>%
  # Selecionar variáveis de interesse
  select(country, lifeExp, gdpPercap) %>%
  # Ordenar por expectativa de vida (decrescente)
  arrange(desc(lifeExp))

# Mostrar resultados
resultado_final
# A tibble: 17 × 3
   country        lifeExp gdpPercap
   <fct>            <dbl>     <dbl>
 1 Iceland           81.8    36181.
 2 Switzerland       81.7    37506.
 3 Spain             80.9    28821.
 4 Sweden            80.9    33860.
 5 France            80.7    30470.
 6 Italy             80.5    28570.
 7 Norway            80.2    49357.
 8 Austria           79.8    36126.
 9 Netherlands       79.8    36798.
10 Greece            79.5    27538.
11 Belgium           79.4    33693.
12 United Kingdom    79.4    33203.
13 Germany           79.4    32170.
14 Finland           79.3    33207.
15 Ireland           78.9    40676.
16 Denmark           78.3    35278.
17 Portugal          78.1    20510.

Observe o fluxo de análise:

  1. Filtramos os dados com critérios específicos
  2. Selecionamos apenas as variáveis de interesse
  3. Ordenamos os resultados para facilitar a interpretação
  4. Todo o processo forma um “pipeline” de análise limpo e legível

8.2.12 Resumo: Função filter()

O que você precisa lembrar
  1. Para que serve: Selecionar apenas as linhas (observações) que atendem a determinadas condições

  2. Sintaxe básica:

dados %>% filter(condição1, condição2, ...)
  1. Comparações mais usadas:

    • Igual: == (dois sinais de igual!)
    • Diferente: !=
    • Maior/Menor: >, <, >=, <=
  2. Múltiplas condições:

    • Todas as condições (E): filter(condição1 & condição2)
    • Qualquer condição (OU): filter(condição1 | condição2)
  3. Lembre-se sempre de salvar o resultado:

nova_df <- dados %>% filter(...)

8.3 Função mutate()

O que é a função mutate()?
  • 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
Sintaxe da função mutate()
# Formato básico
dados %>% mutate(nova_coluna = expressão)

# Exemplos práticos
dados %>% mutate(valor_total = preco * quantidade)
dados %>% mutate(valor_com_desconto = preco * 0.9)

O que cada parte significa:

  • nova_coluna: Nome da nova variável que você está criando
  • expressão: Fórmula que calcula os valores da nova variável
  • A expressão é aplicada a cada linha individualmente
Aplicação: Análise de Vendas

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).

8.3.1 Criando categorias com ifelse()

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 categorias com ifelse
paises_categorizados <- gapminder %>%
  filter(year == 2007) %>%
  mutate(
    nivel_desenvolvimento = ifelse(gdpPercap > 10000, 
                                   "Desenvolvimento Alto", 
                                   "Desenvolvimento Baixo")
  ) %>%
  select(country, gdpPercap, nivel_desenvolvimento) %>%
  head(6)

paises_categorizados
  • É como dizer: “SE o PIB per capita for maior que 10.000, então classifique como ‘Desenvolvimento Alto’, SENÃO classifique como ‘Desenvolvimento Baixo’”
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.

8.3.2 Criando Múltiplas Categorias com case_when()

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:

  • Cada linha representa uma condição: condição ~ "valor a atribuir"
  • As condições são verificadas em ordem (de cima para baixo)
  • Quando uma condição é verdadeira, o valor correspondente é atribuído
Quando usar ifelse() vs. case_when()?
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

8.3.3 Erros Comuns e Como Evitá-los

Os erros que todos cometem no início
  1. Usar o operador de atribuição errado

    • ERRADO: mutate(nova_var <- expressão)
    • CORRETO: mutate(nova_var = expressão)
  2. Esquecer de salvar o resultado

    • ERRADO: dados %>% mutate(nova_var = x * 2) ❌ (resultado não salvo)
    • CORRETO: dados_novos <- dados %>% mutate(nova_var = x * 2)
  3. Tentar usar variáveis que acabou de criar sem manter os resultados

ERRADO:

# Executando dois comandos separados:
dados %>% mutate(nova_var = x * 2)  # Resultado não salvo em lugar nenhum
dados %>% filter(nova_var > 10)     # ❌ Erro! nova_var não existe em 'dados'

CORRETO (Pipeline único):

dados_novos <- dados %>%
  mutate(nova_var = x * 2) %>%
  filter(nova_var > 10) # ✅ Funciona porque tudo está no mesmo pipeline

8.3.4 Resumo: Função mutate()

O que você precisa lembrar
  1. O que faz: mutate() cria novas variáveis ou modifica existentes

  2. Usos comuns no mundo dos negócios:

    • Calcular totais, médias, porcentagens
    • Converter unidades (dólares para reais, unidades para milhares)
    • Criar categorias e classificações
  3. Como usar na prática:

dados %>% mutate(nova_variavel = expressão)
  1. Ferramentas complementares:

    • ifelse() para classificações simples (sim/não)
    • case_when() para classificações múltiplas
  2. Lembre-se de salvar o resultado em um novo objeto:

novo_df <- dados %>% mutate(...)

8.4 Funções group_by() + summarize()

O que são as funções group_by() e summarize()?
  • 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)

Funções group_by() e summarize()?
Sintaxe das funções group_by() e summarize()
# Estrutura básica
df %>% 
  group_by(variavel_de_agrupamento) %>%
  summarize(nome_do_resumo = funcao(variavel))

# Exemplo prático
df %>%
  group_by(departamento) %>%
  summarize(media_vendas = mean(vendas))
  • df: A data frame que contém os dados
  • variavel_de_agrupamento: Variável categórica pela qual agrupar (ex: região, produto)
  • nome_do_resumo: Nome que você escolhe para o resultado calculado
  • funcao: Função estatística (ex: mean, sum, max, min, sd, n)
  • variavel: Variável para calcular a estatística
Exemplo: Análise Financeira por Continente

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
# A tibble: 5 × 6
  continent PIB_medio Total_populacao Paises_analisados PIB_minimo PIB_maximo
  <fct>         <dbl>           <dbl>             <int>      <dbl>      <dbl>
1 Oceania      29810.        24549947                 2     25185.     34435.
2 Europe       25054.       586098529                30      5937.     49357.
3 Asia         12473.      3811953827                33       944      47307.
4 Americas     11003.       898871184                25      1202.     42952.
5 Africa        3089.       929539692                52       278.     13206.

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 Mais Usadas com summarize()
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.

8.4.1 Agrupando por Múltiplas Variáveis

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:

  • Relatórios de vendas por região e trimestre
  • Análise de desempenho por departamento e mês
  • Monitoramento de métricas por produto e canal de vendas

8.4.2 Erros Comuns e Como Evitá-los

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.

8.4.3 Resumo: Funções group_by() e summarize()

O que você precisa lembrar
  1. 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)

  2. Sintaxe básica:

dados %>% 
  group_by(categoria) %>%
  summarize(resumo = funcao(variavel))
  1. Funções estatísticas básicas:

    • Para totais: sum()
    • Para médias: mean()
    • Para contagens: n()
    • Para mínimos/máximos: min(), max()
  2. Fluxo de trabalho típico:

    • Primeiro filtre os dados (filter())
    • Depois agrupe (group_by())
    • Em seguida calcule estatísticas (summarize())
    • Por fim, ordene os resultados (arrange())
  3. Lembre-se sempre de salvar o resultado:

relatorio_final <- dados %>% group_by(...) %>% summarize(...)

8.5 Função arrange()

Descrição
  • 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
Sintaxe da função arrange()
# Formato básico
df %>% arrange(variavel)         # ordem crescente
df %>% arrange(desc(variavel))   # ordem decrescente

# Ordenar por múltiplas variáveis
dados %>% arrange(var1, var2)       # Ordenar primeiro por var1, depois var2
  • df: A data frame que contém os dados
  • variavel: Nome da coluna pela qual você quer ordenar as observações
  • Use desc() para ordem descrescente (do maior para o menor)
  • Quando ordenando por múltiplas variáveis, a primeira tem prioridade
Aplicação: Análise de Desempenho

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).

8.5.1 Erros Comuns e Como Evitá-los

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!

8.5.2 Resumo: Função arrange()

O que você precisa lembrar
  1. Para que serve: Ordenar as linhas (observações) com base nos valores de uma ou mais colunas

  2. Sintaxe básica:

dados %>% arrange(variavel)         # ordem crescente 
dados %>% arrange(desc(variavel))   # ordem decrescente 
  1. Usos comuns em negócios:

    • Criar rankings de vendedores, produtos ou regiões
    • Identificar os maiores clientes (Top 10)
    • Encontrar problemas (itens com menor desempenho)
    • Preparar dados para relatórios e apresentações
  2. Lembre-se sempre:

    • Use desc() para ordem decrescente
    • Para ordenar por múltiplas colunas: arrange(var1, var2)
    • Salve o resultado em um novo objeto!
dados_ordenados <- dados %>% arrange(...)

8.6 Resumo das Funções dplyr

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 %>%

8.7 Pacote dplyr: Bibliografia Recomendada

9 dplyr: Tipos Básicos de joins

O Problema da Fragmentação de Dados
  • Dados financeiros raramente estão concentrados em uma única base ou sistema:

    • Dados de Mercado: Preços de ativos, volumes, volatilidade em sistemas como Bloomberg ou Economática
    • Demonstrações Financeiras: Balanços patrimoniais, DREs e fluxos de caixa em bases como CVM ou Capital IQ
    • Informações de Governança: Composição de conselhos, estrutura de propriedade em formulários de referência
    • Dados Macroeconômicos: Indicadores como juros, inflação e PIB em bases do Banco Central ou IBGE
  • Análises de dados muitas vezes exigem a integração dessas múltiplas fontes

  • Exemplo: Para estudar a relação entre governança e retorno ajustado ao risco, precisamos combinar:

    • Histórico de preços das ações (base de mercado)
    • Indicadores contábeis como ROE e alavancagem (demonstrações financeiras)
    • Estrutura de propriedade e composição do conselho (dados de governança)
    • Fatores de risco sistemático (dados macroeconômicos)
  • Joins (Uniões) são operações fundamentais para esta integração em pesquisas financeiras empíricas

Joins na Pesquisa Empírica em Finanças
  • Dados Multidimensionais: Pesquisas financeiras tipicamente requerem a integração de:

    • Dados de mercado (preços, retornos, volume)
    • Informações contábeis (balanços, DREs)
    • Indicadores macroeconômicos (PIB, taxas de juros, inflação)
    • Dados de governança corporativa
  • Estudos de Evento: Análises que combinam séries temporais de preços de ativos com datas específicas de eventos corporativos (fusões, aquisições, distribuição de dividendos)

  • Análises de Dados em Painel: Pesquisas que acompanham múltiplas empresas ao longo do tempo, exigindo combinação de dados transversais e longitudinais

  • Reprodutibilidade Científica: Joins documentados garantem que outros pesquisadores possam reproduzir exatamente o mesmo conjunto de dados da análise

9.1 Desafios Específicos de Dados em Finanças

Problemas Comuns em Bases Financeiras
  • Códigos de Identificação Inconsistentes:
    • Empresas podem ter múltiplos identificadores (ticker, CNPJ, código CVM)
    • Mesma empresa pode aparecer com nomes diferentes em bases distintas
    • Subsidiárias e controladoras podem ter tratamentos diferentes
  • Periodicidades Divergentes:
    • Dados de mercado (geralmente diários ou intradiários)
    • Dados contábeis (trimestrais ou anuais)
    • Dados macroeconômicos (mensais, trimestrais)
  • Sobrevivência das Empresas:
    • Empresas que entram/saem da bolsa (IPOs, delisting)
    • Processos de fusão e aquisição alterando a estrutura dos dados
    • Viés de sobrevivência em estudos longitudinais
  • Tratamento Especial para Eventos Financeiros:
    • Splits, bonificações e outros eventos corporativos
    • Reorganizações societárias
    • Mudanças em práticas contábeis (IFRS)

9.2 Aplicações Práticas de Joins na Pesquisa em Finanças

Exemplos de Estudos que podem Aplicar Joins
  • Estudos de Retornos Anormais:

    # Combinar dados de mercado com anúncios de eventos
    estudo_evento <- dados_retornos %>%
      left_join(anuncios_dividendos, by = c("codigo_empresa", "data"))
  • Estudos sobre Governança e Valor:

    # Integrar dados de governança corporativa com desempenho contábil
    analise_governanca <- empresas_dados_contabeis %>%
      left_join(indices_governanca, by = "codigo_cvm") %>%
      left_join(composicao_conselhos, by = c("codigo_cvm", "ano_fiscal"))
  • Modelos de Precificação de Ativos:

    # Combinar fatores de risco com características das empresas
    modelo_multifatorial <- retornos_ativos %>%
      left_join(fatores_mercado, by = "data") %>%
      left_join(caracteristicas_empresas, by = c("codigo_empresa", "ano", "trimestre"))
  • Mercado de Crédito e Ratings:

    # Analisar impacto de mudanças de rating no custo de capital
    analise_credito <- custos_captacao %>%
      inner_join(historico_ratings, by = c("codigo_empresa", "data_emissao"))

9.3 CRISP-DM e Joins

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:

    • Importação de dados (read_csv(), read_xlsx())
    • Organização de dados (pivot_longer()) para análise
    • Limpeza de dados (rename()``,as.___()`)
    • Filtragem (filter()) e seleção (select()) de dados relevantes
    • Transformação de dados (mutate()) para criar novas variáveis
    • Manipulação de dados ( group_by(), summarize() e arrange())
    • Joins: integrando múltiplas fontes em um arquivo de dados coeso
  • Dados bem integrados facilitam as Fases 4 e 5 (Modelagem e Avaliação) por fornecerem uma visão completa do problema

9.4 Joins no dplyr

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 esquerda
    • inner_join(): Mantém apenas correspondências entre as tabelas
    • full_join(): Mantém todas as linhas de ambas as tabelas
    • right_join(): Mantém todas as linhas da tabela da direita
  • São essenciais quando precisamos combinar informações que estão separadas

9.5 Criando Tabelas de Exemplo

Tabela produtos
# Cria a tabela de produtos
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"
)

# exibe a tabela
produtos
# A tibble: 5 × 4
  codigo_produto nome_produto       preco_unitario categoria  
  <chr>          <chr>                       <dbl> <chr>      
1 P001           Notebook Pro                 4500 Eletrônicos
2 P002           Smartphone X                 2800 Eletrônicos
3 P003           Monitor 24pol                1200 Informática
4 P004           Mouse Gamer                   250 Informática
5 P005           Cadeira Ergonômica            950 Mobiliário 
Tabela vendas
# Cria a tabela de vendas
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
)

# exibe a tabela
vendas
# A tibble: 6 × 5
  id_venda codigo_produto id_cliente data_venda quantidade
     <dbl> <chr>          <chr>      <chr>           <dbl>
1        1 P001           C001       2025-04-15          1
2        2 P002           C002       2025-04-16          2
3        3 P003           C001       2025-04-18          2
4        4 P002           C003       2025-04-20          1
5        5 P006           C002       2025-04-22          3
6        6 P004           C004       2025-04-23          4
Tabela Clientes
# Crian a tabela de clientes 
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"
)

# exibe a tabela
clientes
# A tibble: 4 × 3
  id_cliente nome_cliente   cidade        
  <chr>      <chr>          <chr>         
1 C001       Empresa Alpha  São Paulo     
2 C002       Empresa Beta   Rio de Janeiro
3 C003       João Silva     Belo Horizonte
4 C005       Maria Oliveira Recife        
Dados dos Exemlos
produtos
# A tibble: 5 × 4
  codigo_produto nome_produto       preco_unitario categoria  
  <chr>          <chr>                       <dbl> <chr>      
1 P001           Notebook Pro                 4500 Eletrônicos
2 P002           Smartphone X                 2800 Eletrônicos
3 P003           Monitor 24pol                1200 Informática
4 P004           Mouse Gamer                   250 Informática
5 P005           Cadeira Ergonômica            950 Mobiliário 
vendas
# A tibble: 6 × 5
  id_venda codigo_produto id_cliente data_venda quantidade
     <dbl> <chr>          <chr>      <chr>           <dbl>
1        1 P001           C001       2025-04-15          1
2        2 P002           C002       2025-04-16          2
3        3 P003           C001       2025-04-18          2
4        4 P002           C003       2025-04-20          1
5        5 P006           C002       2025-04-22          3
6        6 P004           C004       2025-04-23          4
clientes
# A tibble: 4 × 3
  id_cliente nome_cliente   cidade        
  <chr>      <chr>          <chr>         
1 C001       Empresa Alpha  São Paulo     
2 C002       Empresa Beta   Rio de Janeiro
3 C003       João Silva     Belo Horizonte
4 C005       Maria Oliveira Recife        

Observe que há dados “imperfeitos”:

  • Produto “P006” está nas vendas, mas não na tabela de produtos
  • Cliente “C004” está nas vendas, mas não na tabela de clientes
  • Cliente “C005” está na tabela de clientes, mas não tem vendas

9.6 Chaves em Joins

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

  • Nas funções de join do dplyr, as chaves são especificadas pelo argumento by

9.7 Tipos de Chaves em Bancos de Dados Relacionais

Chaves Primárias e Estrangeiras
  • Chave primária: Identificador único para cada registro em uma tabela

    • Ex: codigo_cliente na tabela de clientes identifica unicamente cada cliente
    • Não pode conter valores duplicados ou nulos
  • Chave estrangeira: Coluna que referencia a chave primária de outra tabela

    • Ex: codigo_cliente na tabela de vendas é uma chave estrangeira
    • Estabelece relações entre tabelas e mantém a integridade referencial
  • Analogia: Pense em chaves como um sistema de CPF

    • A chave primária é como o CPF único de cada pessoa
    • A chave estrangeira é como mencionar o CPF de alguém em um documento
    • Os joins são como reunir documentos diferentes sobre a mesma pessoa usando seu CPF

9.8 Diagrama de Relações com Chaves

Visualizando a relação entre tabelas
Tabela CLIENTES                 Tabela VENDAS
+--------------+            +---------------+
| codigo_cliente| <--------- |codigo_cliente |  
| nome_cliente  |            | id_venda      |
| cidade        |            | data_venda    |
+--------------+            +---------------+
   Chave Primária             Chave Estrangeira
  • Integridade referencial: Garante que relações entre tabelas permaneçam válidas
    • Impede a criação de vendas para clientes inexistentes
    • Fundamental para a confiabilidade dos dados em sistemas empresariais

9.9 Exemplos Comuns de Chaves

Chaves em sistemas empresariais

Exemplos comuns de chaves em sistemas de informação empresariais:

  • “codigo_produto” para relacionar produtos e vendas
  • “codigo_funcionario” para relacionar funcionários e departamentos
  • “numero_pedido” para relacionar pedidos e itens de pedido
  • “codigo_fiscal” para relacionar notas fiscais e itens fiscais
  • “matricula_aluno” em sistemas educacionais
  • “numero_prontuario” em sistemas de saúde

A identificação correta das chaves é fundamental para o sucesso de joins e para garantir a integridade das análises de dados.

9.10 Desafios com Chaves em Joins

Problemas comuns ao trabalhar com chaves
  • Chaves duplicadas:

    • Podem gerar múltiplas linhas no resultado (multiplicação de dados)
    • Exemplo: Um cliente vinculado a várias vendas resulta em múltiplas linhas
  • Chaves ausentes:

    • Resultam em valores NA quando usando left, right ou full joins
    • Exemplo: Vendas sem cliente cadastrado ou produtos sem vendas
  • Inconsistência de tipos:

    • Problemas quando a mesma chave tem tipos diferentes em tabelas distintas
    • Exemplo: código armazenado como texto em uma tabela e número em outra
  • Diferenças de nomenclatura:

    • Quando a mesma informação tem nomes diferentes em sistemas distintos
    • Requer especificação explícita: by = c("codigo_produto" = "codigo")

9.11 Sintaxe Básica de Joins no dplyr

Como usar joins no dplyr (simplificado)
# Formato básico (simples)
resultado <- x %>% 
  tipo_join(y, by = "coluna_comum")

# Exemplo com nossas tabelas
vendas_com_produtos <- vendas %>%
  left_join(produtos, by = "codigo_produto")

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 tabelas
  • left_join: O tipo de join que queremos usar
  • vendas_com_produtos: O resultado da combinação que salvaremos

9.12 Visão Geral dos Joins

Em resumo:
Tipo de Join Função no dplyr Quando usar
Left join left_join() Quando você precisa manter todos os registros da tabela principal (à esquerda)
Inner join inner_join() Quando você precisa apenas dos registros que existem em ambas as tabelas
Full join full_join() Quando você precisa de todos os dados, independentemente de correspondências
Right join right_join() Quando você precisa manter todos os registros da tabela secundária (à direita)

9.13 Left Join

Função left_join()
resultado <- x %>% 
  left_join(y, by = "chave")

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:

    • Quando a primeira tabela é sua tabela principal
    • Quando você precisa preservar todos os registros da primeira tabela
    • Quando você quer adicionar informações extras à sua tabela principal
  • Exemplo: Manter todas as vendas e adicionar dados dos produtos

9.14 Exemplo: Left Join em Pesquisa

Left Join: Análise de Empresas e seus Indicadores Contábeis
# Tabela de empresas listadas
empresas_listadas <- tribble(
  ~codigo_cvm, ~empresa,            ~setor,              ~segmento_listagem,
  "11592",     "Petrobras",         "Petróleo e Gás",    "Nível 2",
  "19615",     "Vale",              "Mineração",         "Novo Mercado",
  "14311",     "Itaú Unibanco",     "Financeiro",        "Nível 1",
  "18112",     "Natura",            "Bens de Consumo",   "Novo Mercado",
  "22691",     "Magazine Luiza",    "Varejo",            "Novo Mercado"
)

# visualiza o resultado
empresas_listadas 
# A tibble: 5 × 4
  codigo_cvm empresa        setor           segmento_listagem
  <chr>      <chr>          <chr>           <chr>            
1 11592      Petrobras      Petróleo e Gás  Nível 2          
2 19615      Vale           Mineração       Novo Mercado     
3 14311      Itaú Unibanco  Financeiro      Nível 1          
4 18112      Natura         Bens de Consumo Novo Mercado     
5 22691      Magazine Luiza Varejo          Novo Mercado     
# Tabela de indicadores contábeis
indicadores_contabeis <- tribble(
  ~codigo_cvm, ~ano_fiscal, ~roa,    ~roe,    ~ebitda_margem,  ~divida_liquida,
  "11592",     2023,         0.089,   0.235,   0.392,           315780000,
  "19615",     2023,         0.112,   0.268,   0.468,           185230000,
  "14311",     2023,         0.064,   0.195,   0.412,           NULL,
  "22691",     2023,         0.052,   0.148,   0.185,           12450000
)
# visualiza o resultado
indicadores_contabeis 
# A tibble: 4 × 6
  codigo_cvm ano_fiscal   roa   roe ebitda_margem divida_liquida
  <chr>           <dbl> <dbl> <dbl>         <dbl> <list>        
1 11592            2023 0.089 0.235         0.392 <dbl [1]>     
2 19615            2023 0.112 0.268         0.468 <dbl [1]>     
3 14311            2023 0.064 0.195         0.412 <NULL>        
4 22691            2023 0.052 0.148         0.185 <dbl [1]>     
# Left join: todas as empresas, mesmo sem indicadores contábeis disponíveis
analise_empresas <- empresas_listadas %>%
  left_join(indicadores_contabeis, by = "codigo_cvm")

# Visualizando o resultado
analise_empresas
# A tibble: 5 × 9
  codigo_cvm empresa        setor     segmento_listagem ano_fiscal    roa    roe
  <chr>      <chr>          <chr>     <chr>                  <dbl>  <dbl>  <dbl>
1 11592      Petrobras      Petróleo… Nível 2                 2023  0.089  0.235
2 19615      Vale           Mineração Novo Mercado            2023  0.112  0.268
3 14311      Itaú Unibanco  Financei… Nível 1                 2023  0.064  0.195
4 18112      Natura         Bens de … Novo Mercado              NA NA     NA    
5 22691      Magazine Luiza Varejo    Novo Mercado            2023  0.052  0.148
# ℹ 2 more variables: ebitda_margem <dbl>, divida_liquida <list>

Observe que:

  • A empresa “Natura” (código CVM “18112”) aparece no resultado

  • Como não há dados contábeis disponíveis para esta empresa, as colunas de indicadores aparecem com NA

  • O left_join é muito utilizado em pesquisas quando queremos manter todas as empresas da amostra, mesmo aquelas com dados incompletos - decisão metodológica comum em estudos com amostras pequenas

9.15 Inner Join

Função inner_join()
resultado <- x %>% 
  inner_join(y, by = "chave")

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

9.16 Exemplo: Inner Join em Pesquisa

Inner Join: Analisando Eventos de Rating e Performance de Bonds
# Tabela de títulos de dívida corporativa (bonds)
titulos_divida <- tribble(
  ~isin,          ~emissor,        ~valor_emissao, ~yield_to_maturity, ~vencimento,
  "BRPETRDBS036", "Petrobras",     1000000000,     0.0785,             "2030-03-15",
  "BRVALEDBF009", "Vale",           750000000,     0.0652,             "2032-10-08",
  "BRITAUDB0025", "Itaú Unibanco",  500000000,     0.0723,             "2028-05-22",
  "BRBTGPDB0017", "BTG Pactual",    650000000,     0.0798,             "2029-08-30",
  "BRCVCODB0032", "Cielo",          350000000,     0.0815,             "2027-11-12"
)
# visualiza o resultado
titulos_divida
# A tibble: 5 × 5
  isin         emissor       valor_emissao yield_to_maturity vencimento
  <chr>        <chr>                 <dbl>             <dbl> <chr>     
1 BRPETRDBS036 Petrobras        1000000000            0.0785 2030-03-15
2 BRVALEDBF009 Vale              750000000            0.0652 2032-10-08
3 BRITAUDB0025 Itaú Unibanco     500000000            0.0723 2028-05-22
4 BRBTGPDB0017 BTG Pactual       650000000            0.0798 2029-08-30
5 BRCVCODB0032 Cielo             350000000            0.0815 2027-11-12
# Tabela de mudanças de rating
mudancas_rating <- tribble(
  ~isin,          ~data_evento,  ~agencia,   ~rating_anterior, ~novo_rating, ~perspectiva,
  "BRPETRDBS036", "2023-05-10",  "Moody's",  "Ba2",            "Ba1",        "Positiva",
  "BRVALEDBF009", "2023-06-22",  "S&P",      "BBB",            "BBB+",       "Estável",
  "BRVALEDBF009", "2023-08-15",  "Fitch",    "BBB",            "BBB+",       "Estável",
  "BRITAUDB0025", "2023-07-08",  "Moody's",  "Ba1",            "Baa3",       "Estável",
  "BRECOPDB0016", "2023-09-14",  "S&P",      "BB-",            "BB",         "Positiva"
)
# visualiza o resultado
mudancas_rating
# A tibble: 5 × 6
  isin         data_evento agencia rating_anterior novo_rating perspectiva
  <chr>        <chr>       <chr>   <chr>           <chr>       <chr>      
1 BRPETRDBS036 2023-05-10  Moody's Ba2             Ba1         Positiva   
2 BRVALEDBF009 2023-06-22  S&P     BBB             BBB+        Estável    
3 BRVALEDBF009 2023-08-15  Fitch   BBB             BBB+        Estável    
4 BRITAUDB0025 2023-07-08  Moody's Ba1             Baa3        Estável    
5 BRECOPDB0016 2023-09-14  S&P     BB-             BB          Positiva   
# Inner join: apenas títulos de dívida que tiveram mudanças de rating
analise_rating_impacto <- titulos_divida %>%
  inner_join(mudancas_rating, by = "isin")

# Visualizando o resultado
analise_rating_impacto
# A tibble: 4 × 10
  isin    emissor valor_emissao yield_to_maturity vencimento data_evento agencia
  <chr>   <chr>           <dbl>             <dbl> <chr>      <chr>       <chr>  
1 BRPETR… Petrob…    1000000000            0.0785 2030-03-15 2023-05-10  Moody's
2 BRVALE… Vale        750000000            0.0652 2032-10-08 2023-06-22  S&P    
3 BRVALE… Vale        750000000            0.0652 2032-10-08 2023-08-15  Fitch  
4 BRITAU… Itaú U…     500000000            0.0723 2028-05-22 2023-07-08  Moody's
# ℹ 3 more variables: rating_anterior <chr>, novo_rating <chr>,
#   perspectiva <chr>

Observe que:

  • O título da “Cielo” (ISIN “BRCVCODB0032”) não aparece no resultado pois não teve mudança de rating no período analisado

  • A mudança de rating do título “BRECOPDB0016” também não aparece no resultado pois este título não está na nossa base de títulos monitorados

  • O inner_join é apropriado para estudos de evento onde queremos analisar apenas os casos onde ocorreu o evento específico (neste caso, mudança de rating)

9.17 Full Join

Função full_join()
resultado <- x %>% 
  full_join(y, by = "chave")

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:

    • Quando você precisa de uma visão completa de todos os dados
    • Quando quer identificar inconsistências entre tabelas
    • Quando é importante não perder nenhum registro de nenhuma tabela
  • Exemplo: Relatório completo de produtos e vendas

9.18 Exemplo: Full Join

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

9.19 Right Join

Função right_join()
resultado <- x %>% 
  right_join(y, by = "chave")

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

9.20 Exemplo: Right Join

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:

  • Agora o produto “P005” (Cadeira Ergonômica) aparece no resultado
  • Como esse produto não tem vendas, as colunas de vendas aparecem com NA
  • O right_join é útil para identificar produtos sem movimento

9.21 Exemplo: Combinando Múltiplas Tabelas

Estudo integrado de Governança, Retorno e Risco Sistêmico
# Tabela de empresas e características de governança
governanca <- tribble(
  ~codigo_negociacao, ~empresa,         ~indice_governanca, ~tipo_controlador, ~comite_auditoria,
  "PETR4",            "Petrobras",      6.8,                "Estatal",         TRUE,
  "VALE3",            "Vale",           8.2,                "Pulverizado",     TRUE,
  "ITUB4",            "Itaú Unibanco",  7.9,                "Familiar",        TRUE,
  "BBDC4",            "Bradesco",       7.6,                "Familiar",        TRUE,
  "MGLU3",            "Magazine Luiza", 7.1,                "Familiar",        FALSE
)
# visualiza o resultado
governanca
# A tibble: 5 × 5
  codigo_negociacao empresa  indice_governanca tipo_controlador comite_auditoria
  <chr>             <chr>                <dbl> <chr>            <lgl>           
1 PETR4             Petrobr…               6.8 Estatal          TRUE            
2 VALE3             Vale                   8.2 Pulverizado      TRUE            
3 ITUB4             Itaú Un…               7.9 Familiar         TRUE            
4 BBDC4             Bradesco               7.6 Familiar         TRUE            
5 MGLU3             Magazin…               7.1 Familiar         FALSE           
# Tabela de retornos anuais ajustados
retornos <- tribble(
  ~codigo_negociacao, ~ano,  ~retorno_anual, ~volatilidade, ~beta,
  "PETR4",            2023,   0.125,          0.285,        1.32,
  "VALE3",            2023,   0.084,          0.215,        1.18,
  "ITUB4",            2023,   0.152,          0.195,        0.87,
  "BBDC4",            2023,   0.138,          0.205,        0.92,
  "ABEV3",            2023,   0.062,          0.165,        0.72
)
# visualiza o resultado
retornos
# A tibble: 5 × 5
  codigo_negociacao   ano retorno_anual volatilidade  beta
  <chr>             <dbl>         <dbl>        <dbl> <dbl>
1 PETR4              2023         0.125        0.285  1.32
2 VALE3              2023         0.084        0.215  1.18
3 ITUB4              2023         0.152        0.195  0.87
4 BBDC4              2023         0.138        0.205  0.92
5 ABEV3              2023         0.062        0.165  0.72
# Tabela de indicadores contábeis
indicadores <- tribble(
  ~codigo_negociacao, ~ano,  ~roa,    ~alavancagem, ~tamanho_ativo,
  "PETR4",            2023,   0.089,   0.325,        395120000,
  "VALE3",            2023,   0.112,   0.285,        312450000,
  "ITUB4",            2023,   0.064,   0.852,        2185620000,
  "BBDC4",            2023,   0.058,   0.815,        1924380000,
  "MGLU3",            2023,   0.052,   0.368,         28540000
)
# visualiza o resultado
indicadores
# A tibble: 5 × 5
  codigo_negociacao   ano   roa alavancagem tamanho_ativo
  <chr>             <dbl> <dbl>       <dbl>         <dbl>
1 PETR4              2023 0.089       0.325     395120000
2 VALE3              2023 0.112       0.285     312450000
3 ITUB4              2023 0.064       0.852    2185620000
4 BBDC4              2023 0.058       0.815    1924380000
5 MGLU3              2023 0.052       0.368      28540000
# Pipeline de análise integrada
analise_integrada <- governanca %>%
  # Primeiro, adicionamos dados de retorno e risco
  left_join(retornos, by = "codigo_negociacao") %>%
  # Depois, adicionamos indicadores contábeis
  left_join(indicadores, by = c("codigo_negociacao", "ano")) %>%
  # Selecionamos apenas as variáveis relevantes para o estudo
  select(
    empresa, codigo_negociacao, ano, indice_governanca, tipo_controlador,
    retorno_anual, volatilidade, beta, 
    roa, alavancagem, tamanho_ativo
  )

# Visualizando o resultado
analise_integrada
# A tibble: 5 × 11
  empresa        codigo_negociacao   ano indice_governanca tipo_controlador
  <chr>          <chr>             <dbl>             <dbl> <chr>           
1 Petrobras      PETR4              2023               6.8 Estatal         
2 Vale           VALE3              2023               8.2 Pulverizado     
3 Itaú Unibanco  ITUB4              2023               7.9 Familiar        
4 Bradesco       BBDC4              2023               7.6 Familiar        
5 Magazine Luiza MGLU3                NA               7.1 Familiar        
# ℹ 6 more variables: retorno_anual <dbl>, volatilidade <dbl>, beta <dbl>,
#   roa <dbl>, alavancagem <dbl>, tamanho_ativo <dbl>

Observe como:

  • Este pipeline combina três conjuntos de dados distintos (governança, mercado e contábil)
  • Empresas como “Magazine Luiza” (MGLU3) aparecem sem dados de retorno (NA)
  • “ABEV3” aparece nos dados de retorno, mas não nas outras tabelas

Implicações metodológicas:

  • O uso de left_join manteve todas as empresas com dados de governança, revelando lacunas nos dados
  • A definição desta amostra de estudo (firmas com dados de governança) é uma escolha metodológica explícita
  • Este tipo de construção de amostra é muito útil em estudos empíricos que analisam relações entre diferentes conjuntos de observações e variáveis.

9.22 Exemplo: Análise de Demonstrações Financeiras

Cenário: Pesquisa em Desempenho Financeiro Setorial
# Tabela com informações básicas das empresas
empresas <- tribble(
  ~codigo_cvm, ~nome_empresa,      ~setor,              ~tamanho,  ~governanca,
  "11592",    "Petrobras S.A.",    "Petróleo e Gás",    "Grande",  "Nível 2",
  "19615",    "Vale S.A.",         "Mineração",         "Grande",  "Novo Mercado",
  "14311",    "Itaú Unibanco S.A.", "Financeiro",       "Grande",  "Nível 1",
  "18112",    "Natura Cosméticos", "Bens de Consumo",   "Médio",   "Novo Mercado",
  "22691",    "Magazine Luiza",    "Varejo",            "Médio",   "Novo Mercado"
)

# visualiza o resultado
empresas
# A tibble: 5 × 5
  codigo_cvm nome_empresa       setor           tamanho governanca  
  <chr>      <chr>              <chr>           <chr>   <chr>       
1 11592      Petrobras S.A.     Petróleo e Gás  Grande  Nível 2     
2 19615      Vale S.A.          Mineração       Grande  Novo Mercado
3 14311      Itaú Unibanco S.A. Financeiro      Grande  Nível 1     
4 18112      Natura Cosméticos  Bens de Consumo Médio   Novo Mercado
5 22691      Magazine Luiza     Varejo          Médio   Novo Mercado
# Tabela de indicadores financeiros trimestrais
indicadores_financeiros <- tribble(
  ~codigo_cvm, ~ano, ~trimestre, ~roa,  ~alavancagem, ~liquidez_corrente, ~margem_ebitda,
  "11592",     2024,  1,          0.032,  0.58,         1.45,              0.28,
  "11592",     2024,  2,          0.041,  0.56,         1.52,              0.31,
  "19615",     2024,  1,          0.045,  0.32,         2.10,              0.34,
  "19615",     2024,  2,          0.048,  0.31,         2.15,              0.36,
  "14311",     2024,  1,          0.018,  0.82,         1.28,              0.42,
  "14311",     2024,  2,          0.019,  0.81,         1.31,              0.41,
  "22691",     2024,  1,          0.028,  0.62,         1.18,              0.12,
  "22691",     2024,  2,          0.025,  0.68,         1.12,              0.10
)
# visualiza o resultado
indicadores_financeiros
# A tibble: 8 × 7
  codigo_cvm   ano trimestre   roa alavancagem liquidez_corrente margem_ebitda
  <chr>      <dbl>     <dbl> <dbl>       <dbl>             <dbl>         <dbl>
1 11592       2024         1 0.032        0.58              1.45          0.28
2 11592       2024         2 0.041        0.56              1.52          0.31
3 19615       2024         1 0.045        0.32              2.1           0.34
4 19615       2024         2 0.048        0.31              2.15          0.36
5 14311       2024         1 0.018        0.82              1.28          0.42
6 14311       2024         2 0.019        0.81              1.31          0.41
7 22691       2024         1 0.028        0.62              1.18          0.12
8 22691       2024         2 0.025        0.68              1.12          0.1 
# Combinando dados para análise de desempenho por setor
analise_setorial <- empresas %>%
  left_join(indicadores_financeiros, by = "codigo_cvm") %>%
  select(nome_empresa, setor, ano, trimestre, roa, alavancagem, margem_ebitda)

# Visualizando o resultado
analise_setorial
# A tibble: 9 × 7
  nome_empresa       setor        ano trimestre    roa alavancagem margem_ebitda
  <chr>              <chr>      <dbl>     <dbl>  <dbl>       <dbl>         <dbl>
1 Petrobras S.A.     Petróleo …  2024         1  0.032        0.58          0.28
2 Petrobras S.A.     Petróleo …  2024         2  0.041        0.56          0.31
3 Vale S.A.          Mineração   2024         1  0.045        0.32          0.34
4 Vale S.A.          Mineração   2024         2  0.048        0.31          0.36
5 Itaú Unibanco S.A. Financeiro  2024         1  0.018        0.82          0.42
6 Itaú Unibanco S.A. Financeiro  2024         2  0.019        0.81          0.41
7 Natura Cosméticos  Bens de C…    NA        NA NA           NA            NA   
8 Magazine Luiza     Varejo      2024         1  0.028        0.62          0.12
9 Magazine Luiza     Varejo      2024         2  0.025        0.68          0.1 

Aplicação em Pesquisa:

  • Este tipo de join permite analisar desempenho financeiro controlando por características específicas das empresas

  • Útil para estudos que investigam:

    • Impacto de governança corporativa nos indicadores contábeis
    • Diferenças de desempenho entre setores
    • Efeito do tamanho da empresa na performance financeira
  • Nota: Observem que “Natura Cosméticos” (código 18112) não aparece nos resultados porque não há dados financeiros correspondentes - situação comum em pesquisas empíricas

9.23 Exemplo: Análise de Retornos Anormais

Cenário: Estudo de Evento sobre Anúncios de Dividendos
# Tabela de preços diários de ações
precos_acoes <- tribble(
  ~ticker,   ~data,          ~preco_fechamento, ~retorno_diario, ~volume,
  "PETR4",   "2024-04-01",   36.75,             0.0125,          15200000,
  "PETR4",   "2024-04-02",   37.30,             0.0150,          18500000,
  "PETR4",   "2024-04-03",   37.05,            -0.0067,          14800000,
  "PETR4",   "2024-04-04",   37.82,             0.0208,          21300000,
  "PETR4",   "2024-04-05",   37.60,            -0.0058,          16900000,
  "VALE3",   "2024-04-01",   68.45,             0.0087,          22400000,
  "VALE3",   "2024-04-02",   68.92,             0.0069,          19800000,
  "VALE3",   "2024-04-03",   70.15,             0.0178,          25600000,
  "VALE3",   "2024-04-04",   71.20,             0.0150,          28300000,
  "VALE3",   "2024-04-05",   70.85,            -0.0049,          23100000
)

# visualiza o resultado
precos_acoes
# A tibble: 10 × 5
   ticker data       preco_fechamento retorno_diario   volume
   <chr>  <chr>                 <dbl>          <dbl>    <dbl>
 1 PETR4  2024-04-01             36.8         0.0125 15200000
 2 PETR4  2024-04-02             37.3         0.015  18500000
 3 PETR4  2024-04-03             37.0        -0.0067 14800000
 4 PETR4  2024-04-04             37.8         0.0208 21300000
 5 PETR4  2024-04-05             37.6        -0.0058 16900000
 6 VALE3  2024-04-01             68.4         0.0087 22400000
 7 VALE3  2024-04-02             68.9         0.0069 19800000
 8 VALE3  2024-04-03             70.2         0.0178 25600000
 9 VALE3  2024-04-04             71.2         0.015  28300000
10 VALE3  2024-04-05             70.8        -0.0049 23100000
# Tabela de anúncios de eventos corporativos
eventos_corporativos <- tribble(
  ~ticker,   ~data_anuncio,   ~tipo_evento,        ~valor,
  "PETR4",   "2024-04-03",    "Dividendo Extra",   2.85,
  "VALE3",   "2024-04-04",    "JCP",               1.75
)
# visualiza o resultado
eventos_corporativos
# A tibble: 2 × 4
  ticker data_anuncio tipo_evento     valor
  <chr>  <chr>        <chr>           <dbl>
1 PETR4  2024-04-03   Dividendo Extra  2.85
2 VALE3  2024-04-04   JCP              1.75
# Realizando análise de retornos nos dias de evento
estudo_evento <- precos_acoes %>%
  inner_join(eventos_corporativos, 
             by = c("ticker", "data" = "data_anuncio")) %>%
  select(ticker, data, tipo_evento, valor, retorno_diario, volume)

# Visualizando o resultado
estudo_evento
# A tibble: 2 × 6
  ticker data       tipo_evento     valor retorno_diario   volume
  <chr>  <chr>      <chr>           <dbl>          <dbl>    <dbl>
1 PETR4  2024-04-03 Dividendo Extra  2.85        -0.0067 14800000
2 VALE3  2024-04-04 JCP              1.75         0.015  28300000

Aplicação em Pesquisa:

  • Este tipo de join é relevante para estudos de evento que analisam o impacto de anúncios corporativos sobre o preço das ações

  • Aplicações em pesquisas financeiras incluem:

    • Reação do mercado a anúncios de distribuição de proventos
    • Avaliação da eficiência informacional em mercados emergentes
    • Impacto de divulgações contábeis e eventos não-recorrentes
  • O inner_join utilizado garante que apenas os dias com eventos são considerados para a análise de retornos anormais

9.24 Fontes Comuns de Dados em Pesquisa Financeira

Bases que Frequentemente Requerem Joins
  • Bases Estruturadas para Pesquisa Acadêmica:
    • Economática: Dados contábeis e de mercado de empresas brasileiras
    • Bloomberg: Dados financeiros globais de alta frequência
  • Fontes Públicas no Brasil:
    • B3: Dados de negociação, índices e eventos corporativos
    • CVM: Demonstrações financeiras padronizadas (DFPs) e formulários de referência
    • Banco Central: Indicadores macroeconômicos e financeiros
    • IBGE: Dados econômicos setoriais e regionais
  • Desafios na Integração:
    • Identificadores divergentes entre bases (códigos CVM vs. tickers vs. CNPJ)
    • Periodicidades diferentes (diária, mensal, trimestral, anual)
    • Diferenças metodológicas na compilação dos dados
    • Tratamento de eventos corporativos (fusões, aquisições, cisões)
  • Estratégias para Joins Eficientes:
    • Criar tabelas de correspondência entre diferentes identificadores
    • Padronizar datas para permitir joins temporais precisos
    • Documentar critérios de exclusão e tratamento de valores ausentes

9.25 Dicas para Uso Eficiente de Joins

Dicas práticas para iniciantes
  1. Conheça seus dados antes de combinar:

    • Verifique se as tabelas têm as “chaves” correspondentes
    • Entenda o que significam valores ausentes (NAs)
  2. Filtre antes de combinar:

    • Se você só precisa de alguns dados, filtre-os antes de fazer joins
    • Isso torna a análise mais rápida e clara
  3. Verifique o resultado:

    • O número de linhas faz sentido?
    • Há valores NA inesperados?
    • Os totais parecem corretos?
  4. Na dúvida, use left_join:

    • É o mais comum e seguro para iniciantes
    • Mantém todos os registros da tabela principal

9.26 O Desafio dos Sistemas Reais

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:

  • O sistema de Vendas pode usar codigo_produto
  • O Cadastro de Produtos pode usar codigo
  • O ERP pode usar cod_prod
  • O sistema legado pode usar id_produto

Resultado: Tentar unir estas tabelas com a sintaxe básica falha:

# Esta tentativa falha:
vendas %>% 
  left_join(produtos, by = "codigo_produto") 
  
# ERRO: 'codigo_produto' não encontrado em 'produtos'

Como resolver este problema comum?

9.27 A Solução

Sintaxe para Colunas com Nomes Diferentes

O dplyr permite especificar explicitamente quais colunas devem ser correspondidas:

# Sintaxe para colunas com nomes diferentes
tabela1 %>%
  left_join(tabela2, by = c("nome_na_tabela1" = "nome_na_tabela2"))

Como interpretar:

  • "nome_na_tabela1": Nome da coluna na primeira tabela (esquerda)
  • "nome_na_tabela2": Nome da coluna na segunda tabela (direita)
  • O operador = estabelece a correspondência entre as colunas

Analogia: Você está criando um “dicionário de tradução” entre os sistemas:

  • “Quando eu digo 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"
)
# visualiza o resultado
produtos_cadastro
# A tibble: 3 × 4
  codigo descricao     valor_unitario categoria  
  <chr>  <chr>                  <dbl> <chr>      
1 P001   Notebook Pro            4500 Eletrônicos
2 P002   Smartphone X            2800 Eletrônicos
3 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
)
# visualiza o resultado
vendas_sistema
# A tibble: 3 × 4
  id_venda cod_produto data_venda   qtd
     <dbl> <chr>       <chr>      <dbl>
1        1 P001        2025-04-15     1
2        2 P002        2025-04-16     2
3        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.

9.28 Resumo: Joins

Pontos-chave para lembrar
  1. Joins unem tabelas que estão separadas

    • Combinam dados de clientes, produtos, vendas, etc.
    • Permitem análises mais completas e informativas
  2. 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 tabelas
    • full_join(): Mantém todos os registros de ambas as tabelas
  3. Na prática, left_join é o mais comum:

    • Mantém todos os registros da tabela principal
    • Adiciona informações complementares quando disponíveis
    • Evita a perda de registros importantes
  4. Comece simples e avance gradualmente:

    • Primeiro faça joins entre duas tabelas
    • Depois adicione mais tabelas conforme necessário
    • Verifique os resultados a cada passo
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:

  • Left = Tudo do lado esquerdo (1ª tabela)
  • Inner = Só o que está nos dois lados
  • Full = Tudo de ambos os lados
  • Right = Tudo do lado direito (2ª tabela)

9.29 Sintaxe Comparativa

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:

  1. A estrutura básica é idêntica para todos os joins:

    • Comece com a primeira tabela
    • Use o operador pipe %>%
    • Aplique a função de join
    • Adicione a segunda tabela e a coluna comum
  2. Só muda o nome da função, que indica qual tipo de join realizar:

    • inner_join, left_join, right_join ou full_join
  3. Quando as colunas têm nomes diferentes, use esta sintaxe:

# Quando colunas têm nomes diferentes nas tabelas
vendas %>% 
  left_join(produtos, by = c("codigo_produto" = "codigo"))
#            ^ coluna na tabela vendas   ^ coluna na tabela produtos

9.30 Onde Aplicar Joins em Pesquisa Financeira

Aplicações práticas em Pesquisa e Análise Financeira
  • Finanças Corporativas:

    • Combinar dados de estrutura de capital com métricas de desempenho para análise de trade-offs
    • Unir séries históricas de dividendos com indicadores de estrutura de propriedade
    • Integrar dados de fusões e aquisições com características específicas das empresas
    • Analisar relações entre estrutura de governança corporativa e custo de capital
  • Mercado de Capitais:

    • Relacionar retornos anormais a eventos corporativos específicos (estudos de evento)
    • Combinar fatores de risco sistemático com características específicas das empresas
    • Unir dados de negociação de alta frequência com anúncios macroeconômicos
    • Integrar preços de ativos com métricas de liquidez e volatilidade implícita
  • Finanças Comportamentais:

    • Integrar dados de transações de investidores individuais com características socioeconômicas
    • Combinar sentiment analysis de notícias financeiras com movimentos de preços
    • Unir dados de pesquisas de percepção de risco com comportamento real de investimento
    • Relacionar características psicométricas com decisões de portfólio
  • Econometria Financeira:

    • Construir painéis de dados balanceados para estimação de modelos longitudinais
    • Combinar séries temporais financeiras com variáveis instrumentais para análises causais
    • Integrar dados de diferentes frequências (diários, mensais, trimestrais) para modelos misto-frequência
    • Unir dados micro e macroeconômicos para análises multiníveis

9.31 Joins: Bibliografia Recomendada

10 Dados Organizados: Potencializando Análises de Dados

Dados Longos = Dados Organizados

Com os dados organizados (formato longo), podemos facilmente, por exemplo:

  • Calcular indicadores de desempenho por categoria e período
  • Calcular indicadores de desempenho por produto e período
  • Analisar tendências mensais para decisões de estoque e marketing
  • etc.

10.1 Aplicações

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.

10.2 Um Pipeline Completo com dplyr

# 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

10.3 Tabelas Profissionais

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:

    • O pacote kableExtra (que veremos a seguir) para relatórios HTML e PDF
    • O pacote gt para tabelas altamente personalizáveis
  • Estes pacotes permitem transformar dados analíticos em tabelas com qualidade profissional, incluindo:

    • título, nomes das colunas e notas formatadas
    • destaque visual para informações importantes
    • personalização de cores, bordas e estilos de texto
    • entre outras.

10.4 O Pacote kableExtra

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.

10.5 Sintaxe Básica do kableExtra

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"
  )
  • kable(): Converte a data frame em tabela básica
  • kable_styling(): Aplica estilos visuais à tabela
  • Outros elementos podem ser adicionados em sequência com o pipe (%>%)
Pipeline para relatórios profissionais

Em projetos de análise de dados completos, o fluxo geralmente é:

  1. Preparar dados com tidyr e dplyr
  2. Analisar dados com dplyr (filter, select, group_by, etc.)
  3. Visualizar resultados com ggplot2 (gráficos) e kableExtra (tabelas)

Um pipeline completo pode é similar com:

# Pipeline completo de análise até apresentação
dados_brutos %>%
  # Fase de limpeza e preparação
  filter(...) %>%
  select(...) %>%
  mutate(...) %>%
  
  # Fase de análise e agregação
  group_by(...) %>%
  summarize(...) %>%
  
  # Fase de apresentação em tabela
  kable(...) %>%
  kable_styling(...) %>%
  column_spec(...)

Este fluxo integrado representa as fases 3, 4 e 6 do CRISP-DM.

10.6 Resumo

Pacote kableExtra
  1. Para que serve: Transformar tabelas de dados simples em tabelas profissionais para relatórios, apresentações e publicações.

  2. Sintaxe básica:

dados %>%
  kable(...) %>%
  kable_styling(...) %>%
  ... outras personalizações ...
  1. Funções principais:

    • kable(): Converte data frame em tabela base
    • kable_styling(): Aplica estilos gerais à tabela
    • column_spec() e row_spec(): Personalizações específicas
    • footnote(): Adiciona notas de rodapé
  2. Integrações estratégicas:

    • Ideal no final de pipelines dplyr para apresentar resultados
    • Complementar aos gráficos do ggplot2 em relatórios
  3. Benefícios em Administração:

    • Eleva a qualidade visual de relatórios gerenciais
    • Facilita a comunicação de insights de dados para gestores
    • Permite destacar KPIs e métricas críticas para tomada de decisão

10.7 Tabela com o Pacote KableExtra

# 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
    )
  )
Tabela 3: Expectativa de Vida (em anos) por Continente (2007)
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

10.8 Exemplo Típico em Administração (Wide)

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

10.9 Transformando para Analise de Dados

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:

  • Cada linha representa uma combinação única de produto, categoria e mês
  • As vendas mensais estão em uma única coluna (valor_vendas)
  • A informação do mês está em uma coluna própria (mes)

10.10 Análise 1 - Nível Básico

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

10.11 Análise 2 - Nível Básico

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

10.12 Análise 3 - Nível Básico

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

10.13 Análise 4 - Nível Intermediário

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

10.14 Análise 4 - Tabela para Apresentação

# 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")
Tabela 4: Desempenho mensal de Vendas por produto
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

10.15 Análise 5 - Nível Intermediário

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

10.16 Análise 6 - Nível Intermediário

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

10.16.1 Funções which.max() e which.min()

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
# Qual o valor máximo?
vendas_mensais[posicao_max]
[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.

10.17 Análise 7 - Nível Avançado

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:

  1. Primeiro agrupamos por produto para realizar a análise para cada item

  2. A função which.max(valor_vendas) retorna a posição (índice) do valor máximo

  3. Ao usar mes[which.max(valor_vendas)], extraímos o nome do mês na posição com valor máximo

  4. 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.

10.18 Análise 7 - Tabela para Apresentação

Tabela 5: Meses de Maior e Menor Venda por Produto
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

10.19 Dados em Seu Ambiente de Trabalho

Reflexão

Considere os dados com os quais você já trabalha ou espera trabalhar em sua carreira:

  1. Que tipos de dados desorganizados você encontra ou espera encontrar?

    • Relatórios gerenciais?
    • Planilhas financeiras?
    • Arquivos de sistemas ERP/CRM?
  2. Como esses dados poderiam ser melhor organizados para análise?

    • Quais são as verdadeiras “observações” nesses dados?
    • Quais são as verdadeiras “variáveis”?
  3. Quais insights de negócio você poderia extrair se esses dados estivessem organizados adequadamente?

    • Padrões temporais?
    • Comparações entre unidades/produtos/regiões?
    • Correlações entre diferentes métricas?
  4. Como você aplicaria o conhecimento desta aula em um exemplo concreto do seu interesse profissional?

  • Dica para sua carreira: Manter um repositório pessoal de códigos R para transformações comuns que você encontra no seu trabalho pode economizar horas de trabalho repetitivo no futuro.

Referências

BROMAN, K. W.; WOO, K. H. Data Organization in Spreadsheets. The American Statistician, v. 72, n. 1, p. 2–10, 2018.