R: R Estatística Descritiva
Última atualização: 2026-08-26
Nas 22 aulas anteriores, aprendemos sobre as “ferramentas” do R — vetores, data frames e ggplot2. Agora, vamos passar para o verdadeiro “valor” do R — a análise estatística. Nesta aula, começaremos com o conceito mais básico: “estatística descritiva”. Usaremos o R para calcular métricas importantes, como média, mediana e desvio-padrão, e “resumir” os dados em alguns números.
Ao concluir esta lição, você será capaz de gerar um “relatório estatístico” para qualquer conjunto de dados usando apenas três linhas de código R.
1. O que você vai aprender
- Estatística descritiva: três categorias principais — medidas de tendência central, medidas de dispersão e forma da distribuição
- Medidas de tendência central: média/mediana/moda
- Dispersão: desvio padrão/variância/IQR/intervalo/mediana absoluta
- Quantis: quantil/mediana/Q1/Q3
- summary() / skimr: Estatísticas rápidas
- dplyr + group_by: Um guia sobre agrupamento
- Prática: Boletim escolar de 1.000 linhas
2. A história do boletim escolar de um aluno
(1) Desafio: Como você “resumiria” 1.000 alunos?
No final do semestre, o professor Bob precisa gerar boletins de notas para 1.000 alunos. Cada aluno está cursando 5 disciplinas e, para cada uma delas, ele precisa calcular:
- Média, mediana (medidas de tendência central)
- Desvio-padrão, quartis (medidas de dispersão)
- Pontuação mais alta, pontuação mais baixa (valores extremos)
- Asimetria, curtose (forma da distribuição)
Cálculos manuais? Fórmulas do Excel? Isso leva duas horas; usando o R summary()——
(2) Solução usando R
# 1. One line summary shows 5 key metrics
summary(scores$math)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 45.0 72.0 82.0 81.5 92.0 99.0
# 2. One line skimr View the full report
library(skimr)
skim(scores$math)
# ── Variable type: numeric ──
# min max mean sd p25 p50 p75 hist
# 45 99 81.5 12 72 82 92 ▇▇▇▇▇
# 3. One line dplyr Grouped Statistics
scores |> group_by(class) |> summarise(
Average Score = mean(math),
Median = median(math),
Standard Deviation = sd(math),
Highest = max(math),
Lowest = min(math),
Number of people = n()
)
3 linhas de código → um boletim escolar completo.
3. Três categorias principais de estatística descritiva
(1) Visão geral das três principais categorias
graph TB
A[Descriptive Statistics] --> B[Central Tendency<br/>Central Tendency]
A --> C[Degree of dispersion<br/>Dispersion]
A --> D[Distribution Patterns<br/>Shape]
B --> E[mean Median mode]
C --> F[sd var range IQR]
D --> G[Skewness skewness<br/>Fengdu kurtosis]
style A fill:#fff3cd
style B fill:#d4edda
style C fill:#cce5ff
style D fill:#f8d7da
(2) Tabela de referência rápida
| Categoria | Função | Significado |
|---|---|---|
| Tendência central | mean() |
Média aritmética |
| Tendência central | median() |
Mediana (50º percentil) |
| Centralizado | mode() |
Modo (requer o pacote DescTools) |
| Discreto | sd() |
Desvio-padrão |
| Discreto | var() |
Variância |
| Discreto | range() |
Valores extremos (mín./máx.) |
| Discreto | IQR() |
Intervalo interquartil (Q3-Q1) |
| Discreto | mad() |
Desvio absoluto mediano |
| Distribuição | skewness() |
Asimetria (requer e1071) |
| Distribuição | kurtosis() |
Kurtose (requer e1071) |
4. Tendência central
(1) mean() Média
x <- c(85, 90, 78, 92, 88)
mean(x) # [1] 86.6
mean(x, na.rm = TRUE) # Skip NA
mean(x, trim = 0.1) # Truncated Mean (Remove the top and bottom 10%)
(2) median() Mediana
median(c(85, 90, 78, 92, 88)) # [1] 88
median(c(85, 90, 78, 92, 10000)) # [1] 90 ← Not affected by 10000 Impact
(3) Modo (Funções especiais)
# R does not have a built-in mode(), use the DescTools package
install.packages("DescTools")
library(DescTools)
Mode(c(1, 2, 2, 3, 3, 3, 4)) # [1] 3
5. Grau de dispersão
(1) sd() / var() Desvio-padrão / Variância
x <- c(85, 90, 78, 92, 88)
sd(x) # [1] 5.32 ← Standard Deviation
var(x) # [1] 28.3 <- Variance (sd^2)
Desvio-padrão = a “distância média” dos pontos de dados em relação à média. Quanto maior o valor, mais dispersos estão os dados.
(2) Valores extremos de range()
x <- c(85, 90, 78, 92, 88)
range(x) # [1] 78 92 ← Minimum and Maximum
diff(range(x)) # [1] 14 ← Range
(3) IQR() Intervalo Interquartil
x <- c(85, 90, 78, 92, 88, 70, 95, 65, 88, 92)
IQR(x) # [1] 11.5 ← Q3 - Q1
quantile(x, c(0.25, 0.5, 0.75))
# 25% 50% 75%
# 78.25 88.0 89.75
Q1 - 1.5*IQR ~ Q3 + 1.5*IQR).
(4) Desvio absoluto da mediana em mad()
mad(c(85, 90, 78, 92, 10000)) # Extremely Robust Discrete Measures
# [1] 4.45
6. Quantis
(1) quantile() Quantil
x <- 1:100
# Default 0%, 25%, 50%, 75%, 100%
quantile(x)
# 0% 25% 50% 75% 100%
# 1.0 25.75 50.5 75.25 100.0
# Custom Percentiles
quantile(x, probs = c(0.1, 0.5, 0.9))
# 10% 50% 90%
# 10.9 50.5 90.1
(2) Percentis comuns
| Percentil | Função | Significado |
|---|---|---|
| Q0 (0%) | min(x) |
Mínimo |
| 1º trimestre (25%) | quantile(x, 0.25) |
Quartil inferior |
| 2º trimestre (50%) | median(x) |
Mediana |
| 3º trimestre (75%) | quantile(x, 0.75) |
Quartil superior |
| 4º trimestre (100%) | max(x) |
Máximo |
7. summary() — Uma única linha de estatísticas resumidas
x <- c(85, 90, 78, 92, 88, NA, 75, 95)
summary(x)
# Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
# 75.00 81.50 88.00 87.62 90.50 95.00 1
6 métricas principais + contagem de NA — tudo em uma única linha!
# Data Frame
df <- data.frame(
age = c(20, 25, 30, 35),
score = c(85, 90, 78, 92)
)
summary(df)
# age score
# Min. :20.00 Min. :78.00
# 1st Qu.:23.75 1st Qu.:83.25
# Median :27.50 Median :87.50
# Mean :27.50 Mean :86.25
# 3rd Qu.:31.25 3rd Qu.:90.50
# Max. :35.00 Max. :92.00
8. skimr: Estatística Avançada e Abrangente
install.packages("skimr")
library(skimr)
x <- c(85, 90, 78, 92, 88, 70, 95, 65, 88, 92)
skim(x)
# ── Data Summary ────────────────────────
# Values x
# Number of rows 10
# Number of distinct 8
# Mean 84.2
# Standard deviation 10.13
# Min 65
# Max 95
# Median 87.5
# ... (More Metrics)
skim() Oferece mais de 20 métricas — 10 vezes mais detalhadas do que summary().
9. Estatística descritiva por grupo
(1) dplyr + group_by + summarise
library(dplyr)
# Simulation 3 Cls × 5 Student Grades
scores <- tibble(
class = rep(c("1Cls", "2Cls", "3Cls"), each = 5),
student = paste0("S", 1:15),
math = c(85, 78, 92, 65, 88, # 1 Cls
90, 75, 80, 95, 70, # 2 Cls
82, 88, 76, 91, 85), # 3 Cls
english = c(78, 85, 88, 70, 92,
82, 80, 90, 88, 75,
88, 90, 78, 92, 85)
)
# Class Statistics
class_stats <- scores |>
group_by(class) |>
summarise(
Number of people = n(),
Mathematical Average = mean(math),
Median in Mathematics = median(math),
Mathematical Standard Deviation = sd(math),
Top in Math = max(math),
Lowest in Math = min(math),
MathematicsIQR = IQR(math),
Average English Score = mean(english)
)
print(class_stats)
# A tibble: 3 × 9
# class Number of people Mathematical Average Median in Mathematics Mathematical Standard Deviation Top in Math Lowest in Math MathematicsIQR Average English Score
# <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1Cls 5 81.6 85 11.4 92 65 17 82.6
# 2 2Cls 5 82 80 10.5 95 70 20 83
# 3 3Cls 5 84.4 85 6.02 91 76 12 86.6
(2) Discriminação por múltiplos indicadores (across)
# Calculate statistics for all numeric columns at once
scores |>
group_by(class) |>
summarise(across(where(is.numeric), list(
mean = mean,
sd = sd,
median = median
)))
(3) Sintaxe antiga para tapply (para referência)
# Use tapply
tapply(scores$math, scores$class, mean)
# 1Cls 2Cls 3Cls
# 81.6 82.0 84.4
10. Exercício prático: Boletim escolar completo para 1.000 alunos
A seguir, apresentamos um exemplo de um fluxo de trabalho completo que reúne todas as estatísticas descritivas abordadas nesta aula.
▶ Exemplo: Relatório abrangente sobre 1.000 alunos e 5 disciplinas
# ============================================
# 1000 Student 5 Course Comprehensive Grade Report
# Features: Complete Descriptive Statistics + Grouping + Ranking
# ============================================
library(dplyr)
library(tidyr)
library(ggplot2)
# 1. Prepare data
set.seed(42)
n <- 1000
students <- tibble(
id = 1:n,
class = sample(c("1Cls", "2Cls", "3Cls", "4Cls", "5Cls"), n, replace = TRUE),
gender = sample(c("M", "F"), n, replace = TRUE),
math = round(rnorm(n, 80, 12)),
english = round(rnorm(n, 78, 15)),
physics = round(rnorm(n, 75, 14)),
chemistry = round(rnorm(n, 76, 13)),
biology = round(rnorm(n, 80, 10))
)
cat("=== Data Volume:", nrow(students), "rows ===\n")
# 2. University-wide Comprehensive Statistics
cat("\n=== University-wide Comprehensive Statistics ===\n")
overall <- students |>
summarise(across(c(math, english, physics, chemistry, biology),
list(mean = mean, sd = sd, median = median),
.names = "{.col}_{.fn}"))
print(overall)
# 3. Statistics by Class
cat("\n=== Math Statistics for Each Class ===\n")
class_stats <- students |>
group_by(class) |>
summarise(
Number of people = n(),
Average = round(mean(math), 2),
Median = median(math),
Standard Deviation = round(sd(math), 2),
Highest = max(math),
Lowest = min(math),
Q1 = quantile(math, 0.25),
Q3 = quantile(math, 0.75),
IQR = round(IQR(math), 2)
) |>
arrange(desc(Average))
print(class_stats)
# 4. Grouped by gender
cat("\n=== All genders 5 Class Average ===\n")
gender_stats <- students |>
group_by(gender) |>
summarise(across(c(math, english, physics, chemistry, biology),
mean, .names = "{.col}_Average"))
print(gender_stats)
# 5. Each Student's Total Score and Rank
cat("\n=== Top 10 Students (Total Score) ===\n")
students <- students |>
mutate(total = math + english + physics + chemistry + biology,
average = round(total / 5, 2))
top10 <- students |>
arrange(desc(total)) |>
head(10) |>
select(id, class, gender, total, average)
print(top10)
# 6. Identify the outliers (IQR method)
cat("\n=== Students with Outliers in Math Scores ====\n")
math_q1 <- quantile(students$math, 0.25)
math_q3 <- quantile(students$math, 0.75)
math_iqr <- IQR(students$math)
lower <- math_q1 - 1.5 * math_iqr
upper <- math_q3 + 1.5 * math_iqr
outliers <- students |>
filter(math < lower | math > upper) |>
select(id, class, math)
cat("Normal Range:", lower, "-", upper, "\n")
cat("Number of outliers:", nrow(outliers), "\n")
print(head(outliers, 5))
# 7. Use summary() to view by subject
cat("\n=== Mathematics summary ===\n")
print(summary(students$math))
# 8. Use skimr for advanced report
library(skimr)
cat("\n=== skimr Report ===\n")
print(skim(students |> select(math, english, physics)))
# 9. Write a report
write_csv(students, "student_report.csv")
write_csv(class_stats, "class_stats.csv")
cat("\n=== The report has been generated ===\n")
Resultado esperado (trecho):
=== Math Statistics for Each Class ===
# A tibble: 5 × 9
class Number of people Average Median Standard Deviation Highest Lowest Q1 Q3 IQR
<chr> <int> <dbl> <dbl> <dbl> <int> <int> <dbl> <dbl> <dbl>
1 5Cls 201 81.0 81 12.0 114 44 72 90 18
2 1Cls 195 80.6 81 11.6 115 47 73 88 15
3 3Cls 203 79.8 80 11.8 110 49 71 88 17
4 2Cls 201 79.4 80 12.1 109 44 70 88 18
5 4Cls 200 79.1 79 12.4 116 45 70 89 19
❓ Perguntas Frequentes
P: Média ou mediana? R: Use a média para dados simétricos e a mediana para dados assimétricos. A média é geralmente usada por padrão, mas a mediana é utilizada para dados assimétricos, como renda, preços de imóveis e tempos de espera.
P: sd ou var? R: Use sd de forma consistente para todas as unidades (as mesmas unidades dos dados originais); var é o quadrado de sd (as unidades são os dados originais²).
sd(x) = sqrt(var(x)).
P: Qual devo escolher,
summary()ouskim()? R:summaryé conciso (6 métricas), enquantoskimé detalhado (mais de 20 métricas). Usesummarypara uma visão geral rápida eskimpara uma análise aprofundada.
P: Como se deve lidar com NA? R: Adicione
na.rm = TRUEa todas as funções para ignorar NA. Caso contrário, os resultados para vetores que contenham NA serão todos NA.
P: Como o IQR é usado para identificar valores atípicos? R: Definição padrão: Valores atípicos = < Q1 - 1,5×IQR ou > Q3 + 1,5×IQR. Esse método é mais robusto do que a regra do desvio padrão (pois não pressupõe uma distribuição normal).
P: Como se calculam a assimetria e a curtose? R: Use
e1071::skewness()ee1071::kurtosis(). Se a assimetria for > 0, a distribuição é assimétrica para a direita; se for < 0, é assimétrica para a esquerda. Se a curtose for > 0, a distribuição é mais acentuada do que uma distribuição normal; se for < 0, ela é mais achatada.
📖 Resumo
- As estatísticas descritivas dividem-se em três categorias principais: Tendência central (média/mediana/moda), Medida de dispersão (desvio padrão/variância/IQR) e Forma da distribuição (assimetria/curtose)
- A média é influenciada por valores atípicos, enquanto a mediana é mais robusta — para distribuições assimétricas, use a mediana em primeiro lugar
- sd é o desvio-padrão nas mesmas unidades dos dados originais, e var é sd²
- IQR = Q3 - Q1, uma medida robusta de dispersão comumente utilizada para a detecção de valores atípicos
summary(x)6 métricas por linha, as mais utilizadas;skim(x)mais de 20 métricas, relatório detalhado- Descrição do grupo:
dplyr::group_by() |> summarise(across(where(is.numeric), mean)) - Processamento NA: Adicionar
na.rm = TRUEa todas as funções - Valores atípicos: < Q1 - 1,5×IQR ou > Q3 + 1,5×IQR (robusto)
📝 Exercícios
-
Problema básico: Construa um vetor
x <- c(85, 90, 78, 92, 88, NA, 75, 95), calcule os valores usandomean(),median(),sd()evar()(observena.rm = TRUE) e verifique os 8 resultados. -
Exercício básico: Use
summary()equantile(x, c(0, 0.25, 0.5, 0.75, 1))para calcular as métricas estatísticas do mesmo vetor e compare os dois resultados. -
Problema básico: Crie um data frame (3 turmas × 5 alunos × 2 disciplinas: Matemática e Inglês) e use
dplyr::group_by + summarise + acrosspara calcular a média e o desvio padrão de todas as disciplinas em todas as turmas em uma única operação. -
Exercício avançado: Simule as notas de 1.000 alunos em 5 disciplinas, use
skimr::skim()para gerar um relatório completo, identifique valores atípicos nas notas de matemática (usando o método do IQR) e calcule a porcentagem de alunos com notas atípicas. -
Desafio: Fluxo de trabalho completo — simule as notas de 1.000 alunos em 5 disciplinas: ① Descrição geral ② Descrição agrupada por turma ③ Descrição agrupada por gênero ④ Classificação ⑤ Detecção de valores atípicos ⑥ Gere um relatório em CSV + um relatório em texto Markdown (use
knitr::kable()para renderizar tabelas). Salve capturas de tela do processo.