Fundamentos teóricos e aplicação em dados agrícolas simulados no R - Para fins didáticos
Esta aula foi construída para mostrar que o R vai muito além da análise estatística. Ele se conecta, ele escala, ele vai para produção.
Essa é a Meguy, minha gatinha linda e a mascote do Café com R.
Inscreva-se já no Link.
Bloco 1 - Medidas de Tendência Central
Bloco 2 - Medidas de Dispersão
400 municípios agrícolas brasileiros simulados com estrutura realista por região:
regiao: Norte, Nordeste, Centro-Oeste, Sudeste e Sulcultura: cultura principal do município (Soja, Milho, Cana, Café, Algodão)temperatura_media: temperatura média anual em graus Celsiusprecipitacao_anual: precipitação acumulada anual em milímetrosprodutividade: produtividade por hectare em kg/haarea_plantada: área plantada em hectaresmecanizacao_pct: percentual de área com mecanização| municipio | regiao | cultura | temperatura_media | precipitacao_anual | produtividade | mecanizacao_pct |
|---|---|---|---|---|---|---|
| Mun_001 | Sudeste | Cafe | 22.2 | 1296 | 2039 | 33.0 |
| Mun_002 | Sudeste | Cana | 23.5 | 1511 | 65639 | 68.1 |
| Mun_003 | Centro-Oeste | Soja | 21.8 | 1899 | 3466 | 30.2 |
O que observar nas primeiras linhas:
cultura estrutura toda a análise descritiva, pois as escalas de produtividade são incomparáveis entre culturas sem estratificaçãoprodutividade e precipitacao_anual estão em escalas muito diferentes entre grupos, o que exige atenção na escolha das medidas descritivasdf |>
select(temperatura_media, precipitacao_anual,
produtividade, area_plantada, mecanizacao_pct) |>
skim() |>
as_tibble() |>
select(skim_variable, numeric.mean, numeric.sd,
numeric.p25, numeric.p75, numeric.hist) |>
rename(
Variavel = skim_variable,
Media = numeric.mean,
DP = numeric.sd,
Q1 = numeric.p25,
Q3 = numeric.p75,
Histograma = numeric.hist) |>
mutate(across(where(is.numeric), ~ round(.x, 2))) |>
kable(caption = "Resumo descritivo das variáveis numéricas") |>
kable_styling(
bootstrap_options = c("striped","hover"),
full_width = TRUE, font_size = 12)| Variavel | Media | DP | Q1 | Q3 | Histograma |
|---|---|---|---|---|---|
| temperatura_media | 23.33 | 3.31 | 21.17 | 26.00 | ▂▅▇▇▁ |
| precipitacao_anual | 1500.22 | 494.07 | 1200.75 | 1760.50 | ▃▅▇▂▁ |
| produtividade | 12940.79 | 23997.21 | 1778.00 | 5707.00 | ▇▁▁▁▁ |
| area_plantada | 4093.11 | 10625.71 | 839.25 | 4529.75 | ▇▁▁▁▁ |
| mecanizacao_pct | 37.21 | 15.61 | 27.00 | 41.00 | ▂▇▂▁▁ |
O que o resumo revela:
produtividade tem média muito superior às demais variáveis em termos absolutos, refletindo a escala da cana-de-açúcar em kg/haarea_plantada apresenta Q1 e Q3 muito distantes da média, indicando assimetria positiva e necessidade de transformação logarítmica para análisemecanizacao_pct é a variável mais homogênea, com menor distância entre Q1 e Q3Histograma é a primeira indicação visual da forma de cada distribuiçãoMedidas de tendência central descrevem o valor em torno do qual os dados se concentram:
A média aritmética \(\bar{x}\) é a soma de todos os valores dividida pelo número de observações:
\[\bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_i\]
Parâmetros e propriedades:
A mediana \(\tilde{x}\) é o valor que ocupa a posição central após ordenação crescente:
\[\tilde{x} = \begin{cases} x_{\left(\frac{n+1}{2}\right)} & \text{se } n \text{ é ímpar} \\ \dfrac{x_{\left(\frac{n}{2}\right)} + x_{\left(\frac{n}{2}+1\right)}}{2} & \text{se } n \text{ é par} \end{cases}\]
Propriedades:
A moda é o valor com maior frequência absoluta:
Critério quantitativo de assimetria:
\[\text{Assimetria normalizada} = \frac{|\bar{x} - \tilde{x}|}{s}\]
Quando esse valor supera 0,2, a distribuição é assimétrica e a mediana é mais representativa.
Regra de escala para tendência central:
regiao e cultura, apenas a moda tem interpretação válida| Medida | Escala válida | Sensível a outliers |
|---|---|---|
| Média | Intervalar e racional | Sim |
| Mediana | Ordinal, intervalar e racional | Não |
| Moda | Nominal, ordinal, intervalar e racional | Não |
| Situação | Medida recomendada |
|---|---|
| Distribuição simétrica, sem outliers | Média |
| Distribuição assimétrica ou com outliers | Mediana |
| Variável | Medida recomendada | Justificativa |
|---|---|---|
temperatura_media |
Média | Distribuição aproximadamente simétrica |
precipitacao_anual |
Mediana | Assimetria positiva por região |
area_plantada |
Mediana | Forte assimetria positiva (log-normal) |
df |>
group_by(cultura) |>
summarise(
n = n(),
media = round(mean(produtividade), 1),
mediana = round(median(produtividade), 1),
dp = round(sd(produtividade), 1),
assimetria = round(
(mean(produtividade) - median(produtividade)) / sd(produtividade), 3),
.groups = "drop") |>
kable(
col.names = c("Cultura","n","Média","Mediana","DP","Assim. norm."),
caption = "Tendência central da produtividade (kg/ha) por cultura") |>
kable_styling(
bootstrap_options = c("striped","hover"),
full_width = TRUE, font_size = 12)| Cultura | n | Média | Mediana | DP | Assim. norm. |
|---|---|---|---|---|---|
| Soja | 130 | 3251.4 | 3276.5 | 435.6 | -0.058 |
| Milho | 87 | 5770.6 | 5696.0 | 642.8 | 0.116 |
| Cana | 57 | 71128.6 | 70310.0 | 8160.3 | 0.100 |
| Cafe | 44 | 1638.7 | 1653.0 | 272.6 | -0.053 |
| Algodao | 82 | 1526.3 | 1510.5 | 238.1 | 0.066 |
O que a tabela revela:
Assim. norm. é o critério formal para decidir entre média e medianaComo usar o critério na prática:
media_p <- mean(df$produtividade)
mediana_p <- median(df$produtividade)
df |>
ggplot(aes(x = produtividade)) +
geom_histogram(
bins = 35, fill = cores_cafe["azul_claro"],
color = "white", alpha = 0.85) +
geom_vline(
xintercept = media_p, color = cores_cafe["azul_escuro"],
linewidth = 1.2, linetype = "dashed") +
geom_vline(
xintercept = mediana_p, color = cores_cafe["marrom"],
linewidth = 1.2, linetype = "dotted") +
annotate(
"text", x = media_p + 2500, y = 50,
label = paste0("Média = ", round(media_p, 0)),
color = cores_cafe["azul_escuro"], fontface = "bold", size = 3.5) +
annotate(
"text", x = mediana_p - 2500, y = 43,
label = paste0("Mediana = ", round(mediana_p, 0)),
color = cores_cafe["marrom"], fontface = "bold", size = 3.5, hjust = 1) +
labs(
title = "Distribuição da Produtividade Agrícola",
subtitle = "Linha tracejada = média | Linha pontilhada = mediana",
x = "Produtividade (kg/ha)", y = "Frequência",
caption = "Jennifer Lopes | Café com R") +
temaO que o gráfico revela:
medias_cultura <- df |>
group_by(cultura) |>
summarise(media = mean(produtividade), .groups = "drop")
df |>
ggplot(aes(x = produtividade, fill = cultura)) +
geom_density(alpha = 0.75, color = "white") +
geom_vline(
data = medias_cultura,
aes(xintercept = media, color = cultura),
linewidth = 1, linetype = "dashed") +
scale_fill_manual(values = paleta_culturas) +
scale_color_manual(values = paleta_culturas) +
facet_wrap(~cultura, scales = "free", ncol = 3) +
labs(
title = "Distribuição da Produtividade por Cultura",
subtitle = "Linha tracejada = média de cada cultura",
x = "Produtividade (kg/ha)", y = "Densidade",
caption = "Jennifer Lopes | Café com R") +
tema +
theme(legend.position = "none")O que os painéis revelam:
scales = "free" é obrigatório para visualizar a forma individual de cada distribuiçãoSíntese dos resultados:
Medidas de dispersão quantificam a variabilidade dos dados em torno da tendência central:
A variância amostral \(s^2\) com correção de Bessel:
\[s^2 = \frac{1}{n-1} \sum_{i=1}^{n} (x_i - \bar{x})^2\]
O desvio padrão \(s = \sqrt{s^2}\):
O coeficiente de variação \(CV\):
\[CV = \frac{s}{\bar{x}} \times 100\]
O intervalo interquartílico \(IQR\):
\[IQR = Q_3 - Q_1\]
Os bigodes do boxplot se estendem até os limites de Tukey:
\[L_{\inf} = Q_1 - 1{,}5 \times IQR \qquad L_{\sup} = Q_3 + 1{,}5 \times IQR\]
| Medida | Condição de uso | Sensível a outliers |
|---|---|---|
| Desvio padrão | Distribuição simétrica | Sim |
| IQR | Qualquer distribuição | Não |
| Medida | Condição de uso | Sensível a outliers |
|---|---|---|
| CV | Média positiva e distante de zero | Moderadamente |
| Variância | Inferência e modelagem | Sim |
| Variável | Medida recomendada | Justificativa |
|---|---|---|
temperatura_media |
Desvio padrão | Par da média, distribuição simétrica |
precipitacao_anual |
IQR | Par da mediana, assimetria positiva |
| Comparação entre culturas | CV | Escalas distintas exigem medida adimensional |
df |>
group_by(regiao) |>
summarise(
n = n(),
media = round(mean(precipitacao_anual), 1),
dp = round(sd(precipitacao_anual), 1),
cv_pct = round(sd(precipitacao_anual) / mean(precipitacao_anual) * 100, 1),
q1 = round(quantile(precipitacao_anual, 0.25), 1),
q3 = round(quantile(precipitacao_anual, 0.75), 1),
iqr = round(IQR(precipitacao_anual), 1),
.groups = "drop") |>
kable(
col.names = c("Região","n","Média (mm)","DP (mm)","CV (%)","Q1","Q3","IQR"),
caption = "Dispersão da precipitação anual por região") |>
kable_styling(
bootstrap_options = c("striped","hover"),
full_width = TRUE, font_size = 12)| Região | n | Média (mm) | DP (mm) | CV (%) | Q1 | Q3 | IQR |
|---|---|---|---|---|---|---|---|
| Norte | 36 | 2426.7 | 287.4 | 11.8 | 2250.5 | 2591.0 | 340.5 |
| Nordeste | 79 | 788.0 | 173.0 | 22.0 | 664.0 | 887.5 | 223.5 |
| Centro-Oeste | 128 | 1637.4 | 256.8 | 15.7 | 1463.2 | 1815.2 | 352.0 |
| Sudeste | 88 | 1420.8 | 232.7 | 16.4 | 1257.8 | 1582.8 | 325.0 |
| Sul | 69 | 1679.0 | 208.0 | 12.4 | 1543.0 | 1810.0 | 267.0 |
O que a tabela revela:
df |>
ggplot(aes(
x = reorder(regiao, precipitacao_anual, FUN = median),
y = precipitacao_anual,
fill = regiao)) +
geom_boxplot(alpha = 0.85, outlier.color = "#888888", outlier.size = 1.2) +
stat_summary(fun = mean, geom = "point", shape = 18, size = 3.5, color = "white") +
scale_fill_manual(values = paleta_regioes) +
labs(
title = "Precipitação Anual por Região",
subtitle = "Losango branco = média | Caixa = IQR | Bigodes = 1,5 x IQR",
x = NULL, y = "Precipitação anual (mm)",
caption = "Jennifer Lopes | Café com R") +
tema +
theme(legend.position = "none")O que o boxplot revela:
Sobre a interpretação de outliers:
df |>
ggplot(aes(x = regiao, y = temperatura_media, fill = regiao)) +
geom_violin(alpha = 0.7, color = "white") +
geom_boxplot(width = 0.15, fill = "white", outlier.shape = NA) +
stat_summary(fun = mean, geom = "point", shape = 18, size = 3, color = cores_cafe["azul_escuro"]) +
scale_fill_manual(values = paleta_regioes) +
labs(
title = "Temperatura Média Anual por Região",
subtitle = "Violino = distribuição completa | Caixa = IQR | Losango = média",
x = NULL, y = "Temperatura média anual (°C)",
caption = "Jennifer Lopes | Café com R") +
tema +
theme(legend.position = "none")O que o violin plot revela:
df |>
ggplot(aes(x = reorder(regiao, mecanizacao_pct, FUN = median),
y = mecanizacao_pct,
fill = regiao)) +
geom_boxplot(alpha = 0.85, outlier.color = "#888888", outlier.size = 1.2) +
geom_jitter(width = 0.15, alpha = 0.15, size = 0.8, color = cores_cafe["azul_escuro"]) +
stat_summary(fun = mean, geom = "point", shape = 18, size = 3.5, color = "white") +
scale_fill_manual(values = paleta_regioes) +
labs(
title = "Percentual de Mecanização por Região",
subtitle = "Pontos = municípios individuais | Losango = média | Caixa = IQR",
x = NULL, y = "Mecanização (%)",
caption = "Jennifer Lopes | Café com R") +
tema +
theme(legend.position = "none")O que o gráfico revela:
geom_jitter ao boxplot revela a distribuição real dos municípios por trás do resumo estatísticodf |>
filter(cultura %in% c("Soja","Milho")) |>
ggplot(aes(x = precipitacao_anual, y = produtividade, color = cultura)) +
geom_point(alpha = 0.5, size = 1.8) +
geom_smooth(method = "lm", se = TRUE, linewidth = 1) +
scale_color_manual(values = c(
"Soja" = cores_cafe["azul_escuro"],
"Milho" = cores_cafe["marrom"])) +
facet_wrap(~cultura, scales = "free_y") +
labs(
title = "Precipitação x Produtividade",
subtitle = "Soja e Milho | Reta = regressão linear | Faixa = IC 95%",
x = "Precipitação anual (mm)", y = "Produtividade (kg/ha)",
caption = "Jennifer Lopes | Café com R") +
tema +
theme(legend.position = "none")O que o gráfico revela:
df |>
group_by(cultura) |>
summarise(
media = round(mean(produtividade), 1),
dp = round(sd(produtividade), 1),
cv_pct = round(sd(produtividade) / mean(produtividade) * 100, 1),
.groups = "drop") |>
mutate(
classificacao = case_when(
cv_pct < 15 ~ "Baixa variabilidade",
cv_pct < 30 ~ "Variabilidade moderada",
TRUE ~ "Alta variabilidade")) |>
kable(
col.names = c("Cultura","Média (kg/ha)","DP (kg/ha)","CV (%)","Classificação"),
caption = "Coeficiente de variação da produtividade por cultura") |>
kable_styling(
bootstrap_options = c("striped","hover"),
full_width = TRUE, font_size = 12)| Cultura | Média (kg/ha) | DP (kg/ha) | CV (%) | Classificação |
|---|---|---|---|---|
| Soja | 3251.4 | 435.6 | 13.4 | Baixa variabilidade |
| Milho | 5770.6 | 642.8 | 11.1 | Baixa variabilidade |
| Cana | 71128.6 | 8160.3 | 11.5 | Baixa variabilidade |
| Cafe | 1638.7 | 272.6 | 16.6 | Variabilidade moderada |
| Algodao | 1526.3 | 238.1 | 15.6 | Variabilidade moderada |
O que a tabela revela:
df |>
group_by(cultura) |>
summarise(
cv_pct = round(sd(produtividade) / mean(produtividade) * 100, 1),
.groups = "drop") |>
ggplot(aes(x = reorder(cultura, cv_pct), y = cv_pct, fill = cultura)) +
geom_col(alpha = 0.85, width = 0.6) +
geom_hline(yintercept = 15, linetype = "dashed",
color = cores_cafe["azul_escuro"], linewidth = 0.8) +
geom_hline(yintercept = 30, linetype = "dashed",
color = cores_cafe["marrom"], linewidth = 0.8) +
annotate("text", x = 0.6, y = 16.5, label = "CV = 15%",
color = cores_cafe["azul_escuro"], size = 3.2, hjust = 0) +
annotate("text", x = 0.6, y = 31.5, label = "CV = 30%",
color = cores_cafe["marrom"], size = 3.2, hjust = 0) +
scale_fill_manual(values = paleta_culturas) +
labs(
title = "Coeficiente de Variação da Produtividade por Cultura",
subtitle = "Referências: CV = 15% (baixo) | CV = 30% (alto)",
x = NULL, y = "CV (%)",
caption = "Jennifer Lopes | Café com R") +
tema +
theme(legend.position = "none")O que o gráfico revela:
Boas práticas para comunicação do CV:
Síntese dos resultados:
Regra fundamental das medidas descritivas:
O erro mais comum em análises descritivas:
Quando usar cada medida de posição:
Quando usar cada medida de dispersão:
Referências técnicas utilizadas nesta aula:
Inscreva-se já no Link.

Jennifer Lopes | Café com R | Estatística Descritiva