Projeto da Disciplina

Estatística para Ciência de Dados

Edneide Ramalho

10/March/2026

Pacotes

library(tidyverse)
library(palmerpenguins)
library(ggthemes)
library(nycflights13)
library(skimr)
library(readr)
library(gt)
library(corrplot)
library(GGally)
library(summarytools)
library(gtsummary)
library(rstatix)
library(patchwork)
library(tidyr)

Dados

Vamos usar os dados de churn de clientes. A base de dados original pode ser encontrada no Kaggle: https://www.kaggle.com/datasets/blastchar/telco-customer-churn

dados <- read_csv("dados/churn_clean.csv")
glimpse(dados)
Rows: 7,043
Columns: 21
$ customer_id       <chr> "7590-VHVEG", "5575-GNVDE", "3668-QPYBK", "7795-CFOC…
$ gender            <chr> "Female", "Male", "Male", "Male", "Female", "Female"…
$ senior_citizen    <chr> "No", "No", "No", "No", "No", "No", "No", "No", "No"…
$ partner           <chr> "Yes", "No", "No", "No", "No", "No", "No", "No", "Ye…
$ dependents        <chr> "No", "No", "No", "No", "No", "No", "Yes", "No", "No…
$ tenure            <dbl> 1, 34, 2, 45, 2, 8, 22, 10, 28, 62, 13, 16, 58, 49, …
$ phone_service     <chr> "No", "Yes", "Yes", "No", "Yes", "Yes", "Yes", "No",…
$ multiple_lines    <chr> "No", "No", "No", "No", "No", "Yes", "Yes", "No", "Y…
$ internet_service  <chr> "DSL", "DSL", "DSL", "DSL", "Fiber optic", "Fiber op…
$ online_security   <chr> "No", "Yes", "Yes", "Yes", "No", "No", "No", "Yes", …
$ online_backup     <chr> "Yes", "No", "Yes", "No", "No", "No", "Yes", "No", "…
$ device_protection <chr> "No", "Yes", "No", "Yes", "No", "Yes", "No", "No", "…
$ tech_support      <chr> "No", "No", "No", "Yes", "No", "No", "No", "No", "Ye…
$ streaming_tv      <chr> "No", "No", "No", "No", "No", "Yes", "Yes", "No", "Y…
$ streaming_movies  <chr> "No", "No", "No", "No", "No", "Yes", "No", "No", "Ye…
$ contract          <chr> "Month-to-month", "One year", "Month-to-month", "One…
$ paperless_billing <chr> "Yes", "No", "Yes", "No", "Yes", "Yes", "Yes", "No",…
$ payment_method    <chr> "Electronic check", "Mailed check", "Mailed check", …
$ monthly_charges   <dbl> 29.85, 56.95, 53.85, 42.30, 70.70, 99.65, 89.10, 29.…
$ total_charges     <dbl> 29.85, 1889.50, 108.15, 1840.75, 151.65, 820.50, 194…
$ churn             <chr> "No", "No", "Yes", "No", "Yes", "Yes", "No", "No", "…

Justificativa para a escolha dos dados: esses dados foram escolhidos com o objetivo de identificar e explorar os dados sobre cancelamento de serviços em uma empresa de telecomunicações. Queremos observar dados como tempo de uso do serviço, idade dos usuários e valor pago pelo serviço.

Outros pontos

Função útil

  • Exemplo 1:
dados |> 
  summary()
 customer_id           gender          senior_citizen       partner         
 Length:7043        Length:7043        Length:7043        Length:7043       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
  dependents            tenure      phone_service      multiple_lines    
 Length:7043        Min.   : 0.00   Length:7043        Length:7043       
 Class :character   1st Qu.: 9.00   Class :character   Class :character  
 Mode  :character   Median :29.00   Mode  :character   Mode  :character  
                    Mean   :32.37                                        
                    3rd Qu.:55.00                                        
                    Max.   :72.00                                        
 internet_service   online_security    online_backup      device_protection 
 Length:7043        Length:7043        Length:7043        Length:7043       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
 tech_support       streaming_tv       streaming_movies     contract        
 Length:7043        Length:7043        Length:7043        Length:7043       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
 paperless_billing  payment_method     monthly_charges  total_charges   
 Length:7043        Length:7043        Min.   : 18.25   Min.   :  18.8  
 Class :character   Class :character   1st Qu.: 35.50   1st Qu.: 402.2  
 Mode  :character   Mode  :character   Median : 70.35   Median :1397.5  
                                       Mean   : 64.76   Mean   :2281.9  
                                       3rd Qu.: 89.85   3rd Qu.:3786.6  
                                       Max.   :118.75   Max.   :8684.8  
    churn          
 Length:7043       
 Class :character  
 Mode  :character  
                   
                   
                   
  • Exemplo 2:
dados |> 
  select(-customer_id) |>  
  tbl_summary()
Characteristic N = 7,0431
gender
    Female 3,488 (50%)
    Male 3,555 (50%)
senior_citizen 1,142 (16%)
partner 3,402 (48%)
dependents 2,110 (30%)
tenure 29 (9, 55)
phone_service 6,361 (90%)
multiple_lines 2,971 (42%)
internet_service
    DSL 2,421 (34%)
    Fiber optic 3,096 (44%)
    No 1,526 (22%)
online_security 2,019 (29%)
online_backup 2,429 (34%)
device_protection 2,422 (34%)
tech_support 2,044 (29%)
streaming_tv 2,707 (38%)
streaming_movies 2,732 (39%)
contract
    Month-to-month 3,875 (55%)
    One year 1,473 (21%)
    Two year 1,695 (24%)
paperless_billing 4,171 (59%)
payment_method
    Bank transfer (automatic) 1,544 (22%)
    Credit card (automatic) 1,522 (22%)
    Electronic check 2,365 (34%)
    Mailed check 1,612 (23%)
monthly_charges 70 (36, 90)
total_charges 1,397 (402, 3,789)
churn 1,869 (27%)
1 n (%); Median (Q1, Q3)

Sumário

Para a variável: total_charges, vamos calcular:

  1. a média e mediana para todos os eventos

  2. o desvio padrão

  3. os quantis: 25% e 75%

além disso, vamos calcular o mínimo e o máximo.

# Sumário
dados$total_charges |> 
  summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   18.8   402.2  1397.5  2281.9  3786.6  8684.8 
# Desvio padrão
sd(dados$total_charges)
[1] 2265.27
  • Para um relatório:
dados |> 
  summarise(
    min = min(total_charges, na.rm = TRUE),
    q1 = quantile(total_charges, probs = 0.25, na.rm = TRUE),
    mediana = median(total_charges, na.rm = TRUE),
    media = mean(total_charges, na.rm = TRUE),
    q3 = quantile(total_charges, probs = 0.75, na.rm = TRUE),
    max = max(total_charges, na.rm = TRUE),
    desvio_padrao = sd(total_charges, na.rm = TRUE)
  ) |> 
  gt()
min q1 mediana media q3 max desvio_padrao
18.8 402.225 1397.475 2281.917 3786.6 8684.8 2265.27
  • Usando uma outra função:
dados |> 
  get_summary_stats(total_charges, type = "common") |> 
  gt()
variable n min max median iqr mean sd se ci
total_charges 7043 18.8 8684.8 1397.475 3384.375 2281.917 2265.27 26.992 52.913

Usando o summarytools

descr(dados$total_charges)
Descriptive Statistics  
dados$total_charges  
N: 7043  

                    total_charges
----------------- ---------------
             Mean         2281.92
          Std.Dev         2265.27
              Min           18.80
               Q1          401.95
           Median         1397.47
               Q3         3789.20
              Max         8684.80
              MAD         1810.66
              IQR         3384.38
               CV            0.99
         Skewness            0.96
      SE.Skewness            0.03
         Kurtosis           -0.23
          N.Valid         7043.00
                N         7043.00
        Pct.Valid          100.00

Checando normalidade

dados |> 
  ggplot(aes(total_charges)) +
  geom_histogram(bins = 30, color = "black", fill = "lightblue",
                 alpha = 0.6) +
  theme_minimal()

  • O número de bins utilizado foi o número padrão, ou seja, 30. Esse valor foi escolhido porque consegue mostrar claramente a distribuição dos dados (sem deixar “classes” vazias).

  • Testando visualmente a normalidade dos dados.

    • Pelo histograma, já vemos que a variável não é normal, ou seja, ela é assimétrica à direita. A frequência de valores menores é maior do que de valores mais altos.

    • Ainda assim, vamos checar com os gráficos de densidade e QQplot.

p1 <- dados |> 
  ggplot(aes(x = total_charges)) +
  geom_histogram(
    aes(y = after_stat(density)),
    bins = 30,
    fill = "lightblue",
    color = "white",
    alpha = 0.6
  ) +
  geom_density(color = "darkblue", linewidth = 1.5) +
  theme_minimal() +
  labs(
    title = paste0("Distribuição - Total Charges"),
    x = "Total Charges",
    y = "Densidade"
  )
  
  # QQ plot
  p2 <- dados |> 
  ggplot(aes(sample = total_charges)) +
  stat_qq(size = 2, alpha = 0.6) +
  stat_qq_line(color = "red", linewidth = 1) +
  theme_minimal() +
  labs(
    title = paste0("QQ plot - Total Charges"),
    x = "Quantis Teóricos (Normais)",
    y = "Quantis Amostrais"
  )
  
p1 + p2

Correlação

Calcule a correlação entre todas as variáveis dessa base. Quais são as 3 pares de variáveis mais correlacionadas?

num_vars <- dados |> 
  select(where(is.numeric))
  • Calculando a matriz de correlação:
# Matriz de correlação
matriz_cor <- cor(num_vars, use = "complete.obs")

# Ordenando as maiores correlações 
# Escolhendo somente as 3 maiores 
cormat_long <- as.data.frame(as.table(matriz_cor))
cormat_long |> 
  filter(Freq != 1) |> 
  rename(r = Freq) |>
  distinct(r, .keep_all = TRUE) |> 
  arrange(desc(r)) |> 
  gt()
Var1 Var2 r
total_charges tenure 0.8254641
total_charges monthly_charges 0.6508643
monthly_charges tenure 0.2478999
# Matriz de correlação - gráfica
corrplot(
  matriz_cor, 
  method = "color",
  type = "upper",
  addCoef.col = "gray",
  tl.col = "black",
  tl.srt = 45
)

  • Neste caso os pares mais correlacionados são:

    • tenure e total_charges (r = 0.83, alta)

    • monthly_charges e total_charges (r = 0.65, alta)

    Gráfico de dispersão

dados |> 
  ggplot(aes(x = tenure, y = total_charges)) +
  geom_point(alpha = 0.5) +
  geom_smooth(method = "lm")

A correlação entre as variáveis foi alta (r = 0.83) e isso significa que existe uma forte relação linear entre as variáveis. A linha azul mostra esse ajuste.

Gráfico de linhas

dados |> 
  ggplot(aes(x = tenure, y = total_charges)) +
  geom_line() +
  theme_minimal() +
  labs(
    title = "Gráfico de linha",
    subtitle = "Dados de Churn",
    x = "Tempo na empresa",
    y = "Total pago"
  )