EAE1106 - Métodos Computacionais para Economia
Faculdade de Economia, Administração, Contabilidade e Atuária
Universidade de São Paulo

Prof. Arthur Viaro
1º semestre de 2026


Aula 25 - Manipulação de Dados com Tidyverse

O que é o Tidyverse?

O Tidyverse é uma coleção de pacotes do R projetados para trabalhar juntos. Eles compartilham uma mesma lógica: funções simples, com nomes em inglês claro, que fazem uma coisa só e se encadeiam bem.

Os pacotes que usaremos nesta aula:

Pacote Para quê serve
dplyr Filtrar, ordenar, agrupar, resumir
tidyr Reformatar tabelas (largo ↔︎ longo)
readr Importar arquivos CSV
tibble Tabelas modernas

Analogia com Python/pandas: O Tidyverse em R é, em muitos aspectos, o equivalente ao ecossistema pandas + numpy + matplotlib em Python, mas com uma filosofia mais integrada e consistente.

library(tidyverse)

Tibbles

Um tibble é simplesmente um data.frame melhorado. Ele não faz conversões silenciosas e mostra as dimensões e os tipos de cada coluna automaticamente.

# Criando um tibble manualmente
dados_america_sul <- tibble(
    pais       = c("Brasil", "Argentina", "Chile", "Colômbia", "Peru"),
    pib        = c(2.08, 0.63, 0.32, 0.34, 0.24), # trilhões de USD
    populacao  = c(215, 46, 19, 51, 33), # milhões
    inflacao   = c(4.6, 142.7, 12.8, 11.7, 6.3), # % ao ano
    gini       = c(48.9, 42.3, 44.4, 55.9, 40.2)
)

dados_america_sul
# glimpse() — equivalente ao df.info() do pandas
glimpse(dados_america_sul)
## Rows: 5
## Columns: 5
## $ pais      <chr> "Brasil", "Argentina", "Chile", "Colômbia", "Peru"
## $ pib       <dbl> 2.08, 0.63, 0.32, 0.34, 0.24
## $ populacao <dbl> 215, 46, 19, 51, 33
## $ inflacao  <dbl> 4.6, 142.7, 12.8, 11.7, 6.3
## $ gini      <dbl> 48.9, 42.3, 44.4, 55.9, 40.2

O Operador Pipe |>

O operador pipe (|>) é a peça central do Tidyverse, pois permite executar operações em sequência.

Basicamente, ele passa o resultado da expressão anterior como primeiro argumento da próxima função.

Sem pipe é difícil de ler de dentro para fora:

round(sqrt(mean(c(4, 9, 16, 25))), 2)
## [1] 3.67

Com pipe, lê-se da esquerda para a direita, como uma receita:

c(4, 9, 16, 25) |>
    mean() |>
    sqrt() |>
    round(2)
## [1] 3.67

Atalho no RStudio: Ctrl + Shift + M (configure para usar |> nativo em Tools → Global Options → Code)

Nota histórica: O pipe |> foi introduzido no R 4.1. Em códigos mais antigos você verá %>% do pacote magrittr. Os dois se comportam de forma idêntica na maioria dos casos.


dplyr - As Seis Funções Essenciais

O dplyr tem seis funções principais. Cada uma responde a uma pergunta diferente sobre seus dados:

Pergunta Função
Quais linhas me interessam? filter()
Em que ordem quero ver? arrange()
Quais colunas preciso? select()
Quero calcular algo novo? mutate()
Quero um resumo dos dados? summarize()
Quero o resumo por grupo? group_by()

Vamos usar o dataset nycflights13 — 336.776 voos partindo de Nova York em 2013:

library(nycflights13)
glimpse(flights)
## Rows: 336,776
## Columns: 19
## $ year           <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2…
## $ month          <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ day            <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ dep_time       <int> 517, 533, 542, 544, 554, 554, 555, 557, 557, 558, 558, …
## $ sched_dep_time <int> 515, 529, 540, 545, 600, 558, 600, 600, 600, 600, 600, …
## $ dep_delay      <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2, -2, -1…
## $ arr_time       <int> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 753, 849,…
## $ sched_arr_time <int> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 745, 851,…
## $ arr_delay      <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -3, 7, -1…
## $ carrier        <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV", "B6", "…
## $ flight         <int> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79, 301, 4…
## $ tailnum        <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN", "N394…
## $ origin         <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR", "LGA",…
## $ dest           <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL", "IAD",…
## $ air_time       <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138, 149, 1…
## $ distance       <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 944, 733, …
## $ hour           <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6…
## $ minute         <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0…
## $ time_hour      <dttm> 2013-01-01 05:00:00, 2013-01-01 05:00:00, 2013-01-01 0…

filter() — Escolhendo Linhas

filter() mantém apenas as linhas que satisfazem uma condição lógica.

# Voos de janeiro
flights |> filter(month == 1)
# Múltiplas condições: use vírgula (equivale a E / AND)
flights |> filter(month == 1, day == 1)
# Equivalente:
flights |> filter(month == 1 & day == 1)
# Condição OU: use | ou %in% para conjuntos
flights |> filter(month == 1 | month == 2)
# Equivalente:
flights |> filter(month %in% c(1, 2))
# Voos que chegaram com mais de 2 horas de atraso
flights |> filter(arr_delay > 120)
# Identificar voos cancelados (sem horário de partida registrado)
flights |> filter(is.na(dep_time))

Comparação com Python/pandas:

flights[flights['month'] == 1]
flights[(flights['month'] == 1) & (flights['day'] == 1)]
flights[flights['month'].isin([1, 2])]

arrange() — Ordenando Linhas

Podemos reorganizar as linhas de acordo com uma ou mais variáveis.

# Ordenar por atraso de partida (crescente)
flights |> arrange(dep_delay)
# Maiores atrasos de partida (decrescente)
flights |> arrange(desc(dep_delay))
# Ordenação por múltiplas colunas
flights |> arrange(year, month, day, dep_time)

select() — Escolhendo Colunas

Muitas vezes a base possui dezenas de colunas, mas precisamos trabalhar apenas com algumas delas.

# Selecionar colunas por nome
flights |> select(year, month, day, dep_time, arr_time)
# Funções auxiliares muito úteis
flights |> select(starts_with("dep")) # colunas que começam com "dep"
flights |> select(ends_with("delay")) # colunas que terminam com "delay"
flights |> select(contains("time")) # colunas que contêm "time"
flights |> select(where(is.numeric)) # apenas colunas numéricas
# Renomear coluna ao selecionar
flights |> select(horario_chegada = arr_time)
# Renomear sem descartar as demais colunas
flights |> rename(horario_chegada = arr_time)

mutate() — Criando Novas Colunas

mutate() adiciona colunas calculadas a partir das existentes.

flights |>
    mutate(
        ganho_tempo = dep_delay - arr_delay, # tempo recuperado no ar
        velocidade  = distance / air_time * 60 # milhas por hora
    ) |>
    select(flight, ganho_tempo, velocidade)
# case_when() — condicional "elegante" para criar categorias
flights |>
    mutate(
        categoria = case_when(
            dep_delay < 0 ~ "Adiantado",
            dep_delay == 0 ~ "No horário",
            dep_delay <= 15 ~ "Atraso leve",
            dep_delay <= 60 ~ "Atraso moderado",
            TRUE ~ "Atraso grave"
        )
    ) |>
    count(categoria)

summarize() e group_by() — Resumindo Dados

summarize() colapsa a tabela em uma única linha de estatísticas resumidas.

flights |>
    summarize(
        n_voos      = n(),
        atraso_med  = mean(dep_delay),
        atraso_max  = max(dep_delay)
    )

Por que na.rm = TRUE? Algumas funções como mean() e max() retornam NA se houver qualquer valor faltante nos dados. O argumento na.rm = TRUE diz: “ignore os NAs e calcule com o restante”.

flights |>
    summarize(
        n_voos      = n(),
        atraso_med  = mean(dep_delay, na.rm = TRUE),
        atraso_max  = max(dep_delay, na.rm = TRUE)
    )

A combinação group_by() + summarize() é a mais poderosa do dplyr. Ela calcula o resumo separadamente para cada grupo:

# Atraso médio por mês
flights |>
    group_by(month) |>
    summarize(
        n_voos = n(),
        atraso_medio = mean(dep_delay, na.rm = TRUE),
        pct_atrasado = mean(dep_delay > 0, na.rm = TRUE) * 100,
        .groups = "drop" # Remove agrupamento após summarize
    )

Joins — Unindo Tabelas

Quando a informação está em tabelas diferentes, usamos joins para combiná-las por uma chave comum.

Os tipos de join mais usados são:

Função O que faz
left_join() Mantém todas as linhas da tabela da esquerda
right_join() Mantém todas as linhas da tabela da direita
inner_join() Mantém só as linhas com correspondência em ambas
full_join() Mantém todas as linhas de ambas as tabelas
anti_join() Mantém linhas da esquerda sem correspondência
airlines
# Adicionar o nome completo da companhia aérea à tabela de voos
flights |>
    left_join(airlines, by = "carrier") |>
    select(carrier, name, dep_delay, arr_delay) |>
    head()
airports
# Quais destinos têm maior atraso médio?
flights |>
    group_by(dest) |>
    summarize(atraso = mean(arr_delay, na.rm = TRUE), n = n()) |>
    filter(n > 100) |>
    left_join(airports, by = c("dest" = "faa")) |>
    select(dest, name, atraso, n) |>
    arrange(desc(atraso))

tidyr — Reformatando Tabelas

O que são Dados Tidy?

Um conjunto de dados está no formato tidy quando:

  1. Cada variável é uma coluna
  2. Cada observação é uma linha
  3. Cada valor está em uma única célula

Dados no formato largo são comuns em planilhas, mas difíceis de analisar. Dados no formato longo (tidy) são o que o R espera.

# Formato LARGO — cada ano é uma coluna (não tidy)
tabela_wide <- tibble(
    pais     = c("Brasil", "Argentina", "Chile"),
    pib_2020 = c(1.44, 0.39, 0.25),
    pib_2021 = c(1.61, 0.49, 0.32),
    pib_2022 = c(1.92, 0.63, 0.30)
)

tabela_wide

pivot_longer() — Largo → Longo

tabela_longa <- tabela_wide |>
    pivot_longer(
        cols      = starts_with("pib"), # quais colunas transformar
        names_to  = "ano", # nome da nova coluna de nomes
        values_to = "pib" # nome da nova coluna de valores
    ) |>
    mutate(ano = as.integer(str_remove(ano, "pib_")))

tabela_longa

pivot_wider() — Longo → Largo

tabela_longa |>
    pivot_wider(
        names_from = ano, # valores dessa coluna viram nomes de colunas
        values_from = pib, # valores dessa coluna preenchem a tabela
        names_prefix = "pib_" # prefixo para as novas colunas
    )

readr — Importando Dados

# read_csv() usa vírgula como separador e ponto como decimal (padrão internacional)
dados <- read_csv("dados.csv")

# read_csv2() usa ponto-e-vírgula como separador e vírgula como decimal
dados_br <- read_csv2("dados_brasil.csv")

# Opções úteis
dados <- read_csv(
    "dados.csv",
    na     = c("", "NA", "N/A", "-"), # o que tratar como NA
    skip   = 2 # pular linhas de cabeçalho
)

# Exportar
write_csv(dados, "resultado.csv")

Aplicação: O que explica o crescimento econômico?

Vamos usar a Penn World Table (PWT 10.01), uma das bases de dados mais usadas em macroeconomia comparada, para investigar a relação entre investimento e crescimento do PIB per capita ao longo do tempo.

A Penn World Table fornece dados comparáveis internacionalmente sobre PIB, produtividade, horas trabalhadas, capital físico e muito mais, cobrindo mais de 180 países desde 1950.

# O pacote pwt10 fornece acesso direto à Penn World Table 10.01
# install.packages("pwt10")
library(pwt10)

# Carregar a base
data("pwt10.01")

# Visão geral
glimpse(pwt10.01)
## Rows: 12,810
## Columns: 52
## $ country   <fct> "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba…
## $ isocode   <fct> ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, …
## $ year      <int> 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, …
## $ currency  <fct> Aruban Guilder, Aruban Guilder, Aruban Guilder, Aruban Guild…
## $ rgdpe     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ rgdpo     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pop       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ emp       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ avh       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ hc        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ ccon      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ cda       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ cgdpe     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ cgdpo     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ cn        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ ck        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ ctfp      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ cwtfp     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ rgdpna    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ rconna    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ rdana     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ rnna      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ rkna      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ rtfpna    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ rwtfpna   <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ labsh     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ irr       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ delta     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ xr        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_con    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_da     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_gdpo   <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ i_cig     <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ i_xm      <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ i_xr      <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ i_outlier <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ i_irr     <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ cor_exp   <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ statcap   <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ csh_c     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ csh_i     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ csh_g     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ csh_x     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ csh_m     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ csh_r     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_c      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_i      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_g      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_x      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_m      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_n      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ pl_k      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …

Passo 1 — Entender e Limpar os Dados

# Selecionar as variáveis de interesse e renomear para facilitar
pwt <- pwt10.01 |>
    select(
        pais     = country,
        iso      = isocode,
        ano      = year,
        rgdpna, # PIB real (milhões USD PPP, base 2017)
        pop, # população (milhões)
        emp, # pessoas empregadas (milhões)
        ck, # estoque de capital (milhões USD PPP)
        csh_i, # participação do investimento no PIB (fração)
        avh # horas médias trabalhadas por ano
    ) |>
    mutate(
        pib_pc = rgdpna / pop * 1000 # PIB per capita em USD PPP
    )

glimpse(pwt)
## Rows: 12,810
## Columns: 10
## $ pais   <fct> "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", …
## $ iso    <fct> ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW, ABW…
## $ ano    <int> 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 196…
## $ rgdpna <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ pop    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ emp    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ ck     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ csh_i  <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ avh    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ pib_pc <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
# Quantos países e anos temos?
pwt |>
    summarize(
        n_paises = n_distinct(iso),
        ano_min  = min(ano),
        ano_max  = max(ano),
        n_obs    = n()
    )

Passo 2 — Pergunta de Pesquisa

Os países que mais investiram (como % do PIB) entre 1960 e 2019 cresceram mais?

Esta é uma das questões centrais da teoria do crescimento econômico (Solow, 1956). Vamos explorar os dados.

Passo 3 — Calcular Crescimento e Investimento Médio por País

# Focar no período 1960–2019, excluindo países com dados insuficientes
crescimento_pais <- pwt |>
    filter(ano >= 1960, ano <= 2019) |>
    filter(!is.na(pib_pc), !is.na(csh_i)) |>
    group_by(pais, iso) |>
    # Manter apenas países com pelo menos 40 anos de dados
    filter(n() >= 40) |>
    summarize(
        pib_pc_1960 = first(pib_pc[ano == min(ano)]),
        pib_pc_2019 = last(pib_pc[ano == max(ano)]),
        inv_medio = mean(csh_i, na.rm = TRUE) * 100, # em %
        anos_obs = n(),
        .groups = "drop"
    ) |>
    filter(!is.na(pib_pc_1960), !is.na(pib_pc_2019), pib_pc_1960 > 0) |>
    mutate(
        # Taxa de crescimento anualizada do PIB per capita
        crescimento_anual = (pib_pc_2019 / pib_pc_1960)^(1 / 59) - 1,
        crescimento_anual = crescimento_anual * 100, # em %
        # Categorizar países por nível de investimento
        quartil_inv = ntile(inv_medio, 4),
        grupo_inv = case_when(
            quartil_inv == 1 ~ "Baixo (Q1)",
            quartil_inv == 2 ~ "Médio-baixo (Q2)",
            quartil_inv == 3 ~ "Médio-alto (Q3)",
            quartil_inv == 4 ~ "Alto (Q4)"
        ),
        grupo_inv = factor(grupo_inv, levels = c(
            "Baixo (Q1)", "Médio-baixo (Q2)",
            "Médio-alto (Q3)", "Alto (Q4)"
        ))
    )

crescimento_pais

Passo 4 — Análise Descritiva

# Crescimento médio por quartil de investimento
crescimento_pais |>
    group_by(grupo_inv) |>
    summarize(
        n_paises          = n(),
        inv_medio_pct     = mean(inv_medio),
        crescimento_medio = mean(crescimento_anual),
        crescimento_med   = median(crescimento_anual)
    ) |>
    arrange(grupo_inv)
# Os 10 países que mais cresceram
crescimento_pais |>
    slice_max(crescimento_anual, n = 10) |>
    select(pais, iso, inv_medio, crescimento_anual) |>
    mutate(across(where(is.numeric), \(x) round(x, 2)))
# Os 10 países com menor crescimento
crescimento_pais |>
    slice_min(crescimento_anual, n = 10) |>
    select(pais, iso, inv_medio, crescimento_anual) |>
    mutate(across(where(is.numeric), \(x) round(x, 2)))
# Correlação entre investimento e crescimento
cor_inv_cresc <- cor(
    crescimento_pais$inv_medio,
    crescimento_pais$crescimento_anual,
    use = "complete.obs"
)

cat("Correlação entre taxa de investimento e crescimento:", round(cor_inv_cresc, 3))
## Correlação entre taxa de investimento e crescimento: 0.217
# Onde o Brasil se posiciona?
crescimento_pais |>
    filter(iso == "BRA") |>
    select(pais, inv_medio, crescimento_anual, grupo_inv) |>
    mutate(across(where(is.numeric), \(x) round(x, 2)))

Exercícios

1. Use o dataset flights para encontrar todos os voos que: - Chegaram com mais de 2 horas de atraso, mas saíram no horário - Foram operados pela United (UA), American (AA) ou Delta (DL) - Partiram no verão americano (julho, agosto ou setembro)

2. Para cada mês de 2013, calcule: número de voos, atraso médio de chegada, percentual de voos cancelados. Qual foi o pior mês?

3. Qual aeroporto de origem (EWR, JFK ou LGA) tem o maior atraso médio? Esse resultado é consistente para todas as companhias aéreas?

4. Usando pivot_wider(), crie uma tabela que mostre o atraso médio de chegada por companhia aérea (linhas) e mês (colunas).

5. (Desafio — Penn World Table) A análise acima usou a taxa de investimento como porcentagem do PIB. Refaça a análise usando o estoque de capital por trabalhador (ck / emp) como variável principal. A relação com o crescimento é mais forte ou mais fraca? O que isso sugere teoricamente?


Material baseado em: Wickham, H., Çetinkaya-Rundel, M. & Grolemund, G. (2023). R for Data Science (2ª ed.). O’Reilly. Disponível em: https://r4ds.hadley.nz/