Prática Avançada de Data Science e Visualization

Laboratórios

Olá, tudo bem?

Meu papel nessa disciplina será ajudar no aprendizado da parte dos códigos etc.

Também posso dar pitacos nas apresentações e salvá-los em situações de desespero (atendimentos extras).

Sobre como posso ajudar

Coisas que eu conheço bastante:

  • R / tidyverse
  • extensões do ggplot2
  • htmlwidgets
  • Shiny

Coisas que eu conheço um pouco:

  • Python / pandas
  • seaborn

Dinâmica

Nesse lab, nosso objetivo será construir soluções de transformação e visualização de dados.

  • Os grupos são os que montamos para o trabalho final. Se os grupos ainda não existirem, podemos usar provisioramente os do trimestre passado.

  • As tarefas serão imitar um gráfico que eu montei para vocês usando ggplot2. Eu mostrarei apenas a imagem. Posso dar dicas no meio do caminho.

  • O grupo que conseguir fazer o gráfico primeiro ganhará prêmios.

Base olist

Utilizaremos a base de dados da olist, para que vocês possam aproveitar os trabalhos nas atividades integradoras.

  • Para garantir que as visualizações funcionam, disponibilizei uma base que eu montei (pode conter erros) no material dos labs.

  • A base está tanto em .parquet (usar pacote {arrow}) quanto em .rds (ler com readr::read_rds()). Use a que for mais confortável.

Base olist

olist <- arrow::read_parquet("https://github.com/padsInsper/202433-padsv/releases/download/dados/olist_items.parquet")

dplyr::glimpse(olist)
Rows: 112,650
Columns: 42
$ order_id                      <chr> "00010242fe8c5a6d1ba2dd792cb16214", "000…
$ order_item_id                 <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ product_id                    <chr> "4244733e06e7ecb4970a6e2683c13e61", "e5f…
$ seller_id                     <chr> "48436dade18ac8b2bce089ec2a041202", "dd7…
$ shipping_limit_date           <dttm> 2017-09-19 09:45:35, 2017-05-03 11:05:1…
$ price                         <dbl> 58.90, 239.90, 199.00, 12.99, 199.90, 21…
$ freight_value                 <dbl> 13.29, 19.93, 17.87, 12.79, 18.14, 12.69…
$ customer_id                   <chr> "3ce436f183e68e07877b285a838db11a", "f6d…
$ order_status                  <chr> "delivered", "delivered", "delivered", "…
$ order_purchase_timestamp      <dttm> 2017-09-13 08:59:02, 2017-04-26 10:53:0…
$ order_approved_at             <dttm> 2017-09-13 09:45:35, 2017-04-26 11:05:1…
$ order_delivered_carrier_date  <dttm> 2017-09-19 18:34:16, 2017-05-04 14:35:0…
$ order_delivered_customer_date <dttm> 2017-09-20 23:43:48, 2017-05-12 16:04:2…
$ order_estimated_delivery_date <dttm> 2017-09-29, 2017-05-15, 2018-02-05, 201…
$ product_category_name         <chr> "cool_stuff", "pet_shop", "moveis_decora…
$ product_name_lenght           <dbl> 58, 56, 59, 42, 59, 36, 52, 39, 59, 52, …
$ product_description_lenght    <dbl> 598, 239, 695, 480, 409, 558, 815, 1310,…
$ product_photos_qty            <dbl> 4, 2, 2, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 2…
$ product_weight_g              <dbl> 650, 30000, 3050, 200, 3750, 450, 200, 1…
$ product_length_cm             <dbl> 28, 50, 33, 16, 35, 24, 27, 35, 30, 29, …
$ product_height_cm             <dbl> 9, 30, 13, 10, 40, 8, 5, 75, 12, 3, 25, …
$ product_width_cm              <dbl> 14, 40, 33, 15, 30, 15, 20, 45, 16, 21, …
$ seller_zip_code_prefix        <chr> "27277", "03471", "37564", "14403", "879…
$ seller_city                   <chr> "volta redonda", "sao paulo", "borda da …
$ seller_state                  <chr> "SP", "SP", "MG", "SP", "PR", "SP", "SP"…
$ customer_unique_id            <chr> "871766c5855e863f6eccc05f988b23cb", "eb2…
$ customer_zip_code_prefix      <chr> "28013", "15775", "35661", "12952", "132…
$ customer_city                 <chr> "campos dos goytacazes", "santa fe do su…
$ customer_state                <chr> "RJ", "SP", "MG", "SP", "SP", "MG", "SP"…
$ n_payments                    <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ types                         <chr> "credit_card", "credit_card", "credit_ca…
$ payment_value                 <dbl> 72.19, 259.83, 216.87, 25.78, 218.04, 34…
$ n_reviews                     <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ score                         <dbl> 5, 4, 5, 4, 5, 4, 4, 5, 1, 4, 5, 5, 5, 5…
$ geolocation_lat_seller        <dbl> -22.49818, -23.56626, -22.26409, -20.548…
$ geolocation_lng_seller        <dbl> -44.12361, -46.51842, -46.15856, -47.395…
$ geolocation_city_seller       <chr> "volta redonda", "sao paulo", "borda da …
$ geolocation_state_seller      <chr> "RJ", "SP", "MG", "SP", "PR", "SP", "SP"…
$ geolocation_lat_customer      <dbl> -21.75808, -20.21239, -19.86044, -23.144…
$ geolocation_lng_customer      <dbl> -41.31263, -50.94147, -44.59797, -46.539…
$ geolocation_city_customer     <chr> "campos dos goytacazes", "santa fe do su…
$ geolocation_state_customer    <chr> "RJ", "SP", "MG", "SP", "SP", "MG", "SP"…

Exercício 01 🍪

  • Usar a coluna types

  • Estudar a função theme()

  • As geom_label() ficam na metade da altura da barra.

Exercício 02 🍪🍪

  • Usar scale_x_date()

  • Estudar scale_color_viridis_d()

  • lubridate::floor_date() para aproximar datas

  • case_when() ou fct_other() para reclassificar uma variável categórica

  • filtrar a base para o intervalo de datas entre “2017-01-01” e “2018-07-01”

  • devemos contar/agrupar por data (mês) e estado

Exercício 03 🍪🍪🍪

  • Usar o pacote {ggridges}.

  • Para pintar apenas uma categoria, crie uma coluna.

  • Para anotações no gráfico (como “Mediana”), use a função annotate().

  • Para fazer os reais, use a função scales::scales_dollar_format().

Exercício 04 🍪🍪🍪🍪

  • Faça a contagem por estado, latitude/longtude do seller e customer

  • Filtre para os estados de interesse

  • Use slice_sample() para pegar 1000 observações.

  • Você pode usar essa semente para ficar reprodutível: set.seed(42)

  • Para obter o mapa, usar o pacote {geobr}

  • Para plotar o mapa, usar a função geom_sf()

  • Estamos desenhando CURVAS

  • Use facets

Parte 2

Outra base de dados

Nosso objetivo será construir soluções em R e/ou python para problemas comuns de transformação e visualização de dados.

Leitura dos dados

# A tibble: 6 × 12
     id country_name country_id league_id season    stage date      match_api_id
  <int> <chr>             <int>     <int> <chr>     <int> <chr>            <int>
1     1 Belgium               1         1 2008/2009     1 2008-08-…       492473
2     2 Belgium               1         1 2008/2009     1 2008-08-…       492474
3     3 Belgium               1         1 2008/2009     1 2008-08-…       492475
4     4 Belgium               1         1 2008/2009     1 2008-08-…       492476
5     5 Belgium               1         1 2008/2009     1 2008-08-…       492477
6     6 Belgium               1         1 2008/2009     1 2008-09-…       492478
# ℹ 4 more variables: home_team_api_id <int>, away_team_api_id <int>,
#   home_team_goal <int>, away_team_goal <int>

Exercício 1.1 (transformação) 🛑

glimpse(match_min)
Rows: 25,979
Columns: 12
$ id               <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16…
$ country_name     <chr> "Belgium", "Belgium", "Belgium", "Belgium", "Belgium"…
$ country_id       <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
$ league_id        <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
$ season           <chr> "2008/2009", "2008/2009", "2008/2009", "2008/2009", "…
$ stage            <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, 10…
$ date             <chr> "2008-08-17 00:00:00", "2008-08-16 00:00:00", "2008-0…
$ match_api_id     <int> 492473, 492474, 492475, 492476, 492477, 492478, 49247…
$ home_team_api_id <int> 9987, 10000, 9984, 9991, 7947, 8203, 9999, 4049, 1000…
$ away_team_api_id <int> 9993, 9994, 8635, 9998, 9985, 8342, 8571, 9996, 9986,…
$ home_team_goal   <int> 1, 0, 0, 5, 1, 1, 2, 1, 1, 4, 1, 0, 0, 2, 1, 0, 1, 1,…
$ away_team_goal   <int> 1, 0, 3, 0, 3, 1, 2, 2, 0, 1, 2, 2, 0, 2, 2, 1, 3, 3,…
  • Selecionar as colunas country_id, country_name, home_team_goal, away_team_goal.
  • Filtrar para os campeonatos dos maiores países (Espanha, Inglaterra, Itália, França e Alemanha).
  • Criar uma coluna total_goals, com o total de gols.
  • Calcular a média, a mediana e o desvio padrão de gols por país
  • Ordenar o resultado de forma decrescente pela média
# A tibble: 5 × 4
  country_name media desvio_padrao mediana
  <chr>        <dbl>         <dbl>   <dbl>
1 Germany       2.90          1.70       3
2 Spain         2.77          1.73       3
3 England       2.71          1.69       3
4 Italy         2.62          1.64       2
5 France        2.44          1.55       2

Exercício 1.2 (barras exploratório) 🛑

Exercício 1.3 (barras otimizado) 🛑🛑

  • Utilize case_when() ou case_match() para mudar os nomes dos países.

  • Utilize fct_reorder() para ordenar a coluna country_name adequadamente.

  • Utilize scale_fill_manual() com os valores cores <- c("#C4161C", "#009491")

  • Utilize o ChatGPT para os aspectos estéticos.

Exercício 2.1 (join e pivotagem) 🛑🛑🛑

Rows: 1,458
Columns: 25
$ id                                <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1…
$ team_fifa_api_id                  <dbl> 434, 434, 434, 77, 77, 77, 77, 77, 7…
$ team_api_id                       <dbl> 9930, 9930, 9930, 8485, 8485, 8485, …
$ date                              <chr> "2010-02-22 00:00:00", "2014-09-19 0…
$ build_up_play_speed               <dbl> 60, 52, 47, 70, 47, 58, 62, 58, 59, …
$ build_up_play_speed_class         <chr> "Balanced", "Balanced", "Balanced", …
$ build_up_play_dribbling           <dbl> NA, 48, 41, NA, NA, NA, NA, 64, 64, …
$ build_up_play_dribbling_class     <chr> "Little", "Normal", "Normal", "Littl…
$ build_up_play_passing             <dbl> 50, 56, 54, 70, 52, 62, 45, 62, 53, …
$ build_up_play_passing_class       <chr> "Mixed", "Mixed", "Mixed", "Long", "…
$ build_up_play_positioning_class   <chr> "Organised", "Organised", "Organised…
$ chance_creation_passing           <dbl> 60, 54, 54, 70, 53, 45, 40, 56, 51, …
$ chance_creation_passing_class     <chr> "Normal", "Normal", "Normal", "Risky…
$ chance_creation_crossing          <dbl> 65, 63, 63, 70, 48, 70, 50, 68, 72, …
$ chance_creation_crossing_class    <chr> "Normal", "Normal", "Normal", "Lots"…
$ chance_creation_shooting          <dbl> 55, 64, 64, 70, 52, 55, 55, 57, 63, …
$ chance_creation_shooting_class    <chr> "Normal", "Normal", "Normal", "Lots"…
$ chance_creation_positioning_class <chr> "Organised", "Organised", "Organised…
$ defence_pressure                  <dbl> 50, 47, 47, 60, 47, 40, 42, 41, 49, …
$ defence_pressure_class            <chr> "Medium", "Medium", "Medium", "Mediu…
$ defence_aggression                <dbl> 55, 44, 44, 70, 47, 40, 42, 42, 45, …
$ defence_aggression_class          <chr> "Press", "Press", "Press", "Double",…
$ defence_team_width                <dbl> 45, 54, 54, 70, 52, 60, 60, 60, 63, …
$ defence_team_width_class          <chr> "Normal", "Normal", "Normal", "Wide"…
$ defence_defender_line_class       <chr> "Cover", "Cover", "Cover", "Cover", …
  • Unir a base team_attributes com a base team
  • Filtrar para os times “Real Madrid”, “Bayern”, “Milan”, “PSG” e “Manchester United”
  • Retirar as colunas que acabam com _class
  • Transformar a coluna date em year, contendo o ano
  • Calcular a média das estatísticas por tipo (build_up_play_*, chance_creation_*, defence_*) e empilhar as estatísticas por tipo (não necessariamente nessa ordem).
Rows: 1
Columns: 25
$ id                                <dbl> 16
$ team_fifa_api_id                  <dbl> 47
$ team_api_id                       <dbl> 8564
$ date                              <chr> "2010-02-22 00:00:00"
$ build_up_play_speed               <dbl> 45
$ build_up_play_speed_class         <chr> "Balanced"
$ build_up_play_dribbling           <dbl> NA
$ build_up_play_dribbling_class     <chr> "Little"
$ build_up_play_passing             <dbl> 30
$ build_up_play_passing_class       <chr> "Short"
$ build_up_play_positioning_class   <chr> "Free Form"
$ chance_creation_passing           <dbl> 55
$ chance_creation_passing_class     <chr> "Normal"
$ chance_creation_crossing          <dbl> 45
$ chance_creation_crossing_class    <chr> "Normal"
$ chance_creation_shooting          <dbl> 70
$ chance_creation_shooting_class    <chr> "Lots"
$ chance_creation_positioning_class <chr> "Free Form"
$ defence_pressure                  <dbl> 30
$ defence_pressure_class            <chr> "Deep"
$ defence_aggression                <dbl> 35
$ defence_aggression_class          <chr> "Press"
$ defence_team_width                <dbl> 60
$ defence_team_width_class          <chr> "Normal"
$ defence_defender_line_class       <chr> "Offside Trap"
# A tibble: 90 × 5
    year type    team_short_name team_long_name value
   <dbl> <chr>   <chr>           <chr>          <dbl>
 1  2010 build   ACM             Milan           37.5
 2  2010 chance  ACM             Milan           56.7
 3  2010 defence ACM             Milan           41.7
 4  2011 build   ACM             Milan           57.5
 5  2011 chance  ACM             Milan           53.3
 6  2011 defence ACM             Milan           50  
 7  2012 build   ACM             Milan           47.5
 8  2012 chance  ACM             Milan           45  
 9  2012 defence ACM             Milan           46.7
10  2013 build   ACM             Milan           51  
# ℹ 80 more rows

Exercício 2.2 (linhas exploratório) 🛑🛑

Exercício 2.3 (linhas otimizado) 🛑🛑🛑

  • Utilize case_when() ou case_match() para mudar os nomes da coluna categoria.

  • Utilize o parâmetro legend.position= da função theme()

  • Utilize geom_smooth() para montar a banda de confiança no fundo.

  • Utilize as cores anteriores + um cinza

  • Pode usar o ChatGPT para os aspectos estéticos.