Nesta seção, o conjunto de dados airquality é carregado
e passa por três manipulações simples: criação de uma nova variável,
filtragem e ordenação, seguindo as técnicas apresentadas por Wickham et al.
(2017). Os dados estão no formato tidy, em que cada
coluna é uma variável e cada linha é uma observação (Wickham 2014).
O airquality já vem instalado no R. Ele contém medições
diárias da qualidade do ar em Nova York, de maio a setembro de 1973
(Chambers 2018).
data(airquality)
dados <- airquality
head(dados)
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 NA NA 14.3 56 5 5
## 6 28 NA 14.9 66 5 6
str(dados)
## 'data.frame': 153 obs. of 6 variables:
## $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ...
## $ Solar.R: int 190 118 149 313 NA NA 299 99 19 194 ...
## $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
## $ Temp : int 67 72 74 62 56 66 65 59 61 69 ...
## $ Month : int 5 5 5 5 5 5 5 5 5 5 ...
## $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
Resultado: o conjunto tem 153 linhas (dias) e 6
colunas: ozônio (Ozone), radiação solar
(Solar.R), vento (Wind), temperatura em
Fahrenheit (Temp), mês (Month) e dia
(Day).
colSums(is.na(dados))
## Ozone Solar.R Wind Temp Month Day
## 37 7 0 0 0 0
dados <- dados[complete.cases(dados), ]
nrow(dados)
## [1] 111
Resultado: as colunas Ozone e
Solar.R tinham valores ausentes (NA, Not
Available). Com complete.cases(), foram mantidas
apenas as linhas completas, e restaram 111 dias.
Foi criada a coluna Celsius, que converte a temperatura
de Fahrenheit para Celsius.
dados$Celsius <- round((dados$Temp - 32) / 1.8, 1)
head(dados)
## Ozone Solar.R Wind Temp Month Day Celsius
## 1 41 190 7.4 67 5 1 19.4
## 2 36 118 8.0 72 5 2 22.2
## 3 12 149 12.6 74 5 3 23.3
## 4 18 313 11.5 62 5 4 16.7
## 7 23 299 8.6 65 5 7 18.3
## 8 19 99 13.8 59 5 8 15.0
Resultado: o data frame ganhou a coluna
Celsius. Por exemplo, o primeiro dia teve 67 °F, que
equivalem a 19.4 °C.
Com subset(), foram selecionados apenas os dias com
temperatura acima de 30 °C.
dias_quentes <- subset(dados, Celsius > 30)
nrow(dias_quentes)
## [1] 20
mean(dias_quentes$Ozone)
## [1] 84.8
mean(dados$Ozone)
## [1] 42.0991
Resultado: houve 20 dias acima de 30 °C. Nesses dias, o ozônio médio foi de 84.8 ppb, contra 42.1 ppb no conjunto completo. Ou seja, dias quentes tendem a ter mais ozônio.
Com order(), os dias foram ordenados do maior para o
menor valor de ozônio, e os cinco primeiros são exibidos abaixo.
ordenado <- dados[order(dados$Ozone, decreasing = TRUE), ]
head(ordenado, 5)
## Ozone Solar.R Wind Temp Month Day Celsius
## 117 168 238 3.4 81 8 25 27.2
## 62 135 269 4.1 84 7 1 28.9
## 99 122 255 4.0 89 8 7 31.7
## 121 118 225 2.3 94 8 29 34.4
## 30 115 223 5.7 79 5 30 26.1
Resultado: o dia com mais ozônio foi o dia 25 do mês 8, com 168 ppb e temperatura de 27.2 °C.
A tabela abaixo foi criada com o pacote DT (DataTables), que transforma um data frame em uma tabela interativa. Nela é possível:
datatable(
dados,
caption = "Tabela 1: Dados de qualidade do ar em Nova York (1973), sem valores ausentes.",
filter = "top",
rownames = FALSE,
options = list(pageLength = 10, lengthMenu = c(5, 10, 25, 50))
)
As cinco equações abaixo foram escritas com a sintaxe do LaTeX, que o R Markdown converte automaticamente em fórmulas no relatório (Xie et al. 2018). Todas estão relacionadas às análises feitas neste relatório.
\[s = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}\left(x_i - \bar{x}\right)^2}\]
Significado: mede o quanto os valores \(x_i\) se afastam, em média, da média \(\bar{x}\), sendo \(n\) o número de observações. Quanto maior
\(s\), mais espalhados estão os dados.
No airquality, o desvio padrão do ozônio é 33.3 ppb.
\[r = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i - \bar{x})^2}\;\sqrt{\sum_{i=1}^{n}(y_i - \bar{y})^2}}\]
Significado: mede a força e a direção da relação linear entre duas variáveis \(x\) e \(y\). O valor varia de \(-1\) (relação negativa perfeita) a \(+1\) (relação positiva perfeita), e valores perto de \(0\) indicam relação fraca. Entre ozônio e temperatura, por exemplo, \(r =\) 0.7.
\[z_i = \frac{x_i - \bar{x}}{s}\]
Significado: indica a quantos desvios padrão o valor \(x_i\) está da média. Serve para colocar variáveis de escalas diferentes na mesma régua. Valores com \(|z_i| > 3\) costumam ser tratados como outliers (valores extremos).
\[d(\mathbf{p}, \mathbf{q}) = \sqrt{\sum_{j=1}^{k}\left(p_j - q_j\right)^2}\]
Significado: mede a distância em linha reta entre dois pontos \(\mathbf{p}\) e \(\mathbf{q}\) descritos por \(k\) variáveis. É a medida usada pelo algoritmo KNN (K-Nearest Neighbors, k vizinhos mais próximos) para encontrar os vizinhos mais parecidos. Por isso, os dados devem ser padronizados antes, com o escore z da equação 3.3.
\[Y_i = \beta_0 + \beta_1 X_{i1} + \beta_2 X_{i2} + \cdots + \beta_p X_{ip} + \varepsilon_i, \qquad \hat{\boldsymbol{\beta}} = \left(\mathbf{X}^{\top}\mathbf{X}\right)^{-1}\mathbf{X}^{\top}\mathbf{y}\]
Significado: o modelo explica uma variável resposta \(Y\) (por exemplo, o ozônio) a partir de \(p\) variáveis explicativas \(X\) (por exemplo, temperatura e vento). Os coeficientes \(\beta\) indicam o efeito de cada variável, e \(\varepsilon_i\) é o erro aleatório. A segunda parte é a fórmula de mínimos quadrados, que encontra os coeficientes \(\hat{\boldsymbol{\beta}}\) que minimizam a soma dos erros ao quadrado.
As figuras abaixo foram geradas a partir dos dados manipulados na seção 1. Visualizar os dados é essencial, pois conjuntos com estatísticas resumidas idênticas podem ter comportamentos bem diferentes (Anscombe 1973).
hist(dados$Ozone,
main = "Distribuição do ozônio",
xlab = "Ozônio (ppb)", ylab = "Número de dias",
col = "steelblue", border = "white")
abline(v = mean(dados$Ozone), col = "red", lwd = 2)
abline(v = median(dados$Ozone), col = "darkgreen", lwd = 2)
legend("topright", legend = c("Média", "Mediana"),
col = c("red", "darkgreen"), lwd = 2)
Figura 1: Distribuição da concentração de ozônio.
Interpretação: a maioria dos dias tem pouco ozônio, mas alguns poucos dias têm valores bem altos, formando uma cauda à direita. Por isso, a média (42.1 ppb, linha vermelha) é maior que a mediana (31 ppb, linha verde): os dias extremos puxam a média para cima.
plot(dados$Celsius, dados$Ozone,
main = "Ozônio x Temperatura",
xlab = "Temperatura (°C)", ylab = "Ozônio (ppb)",
pch = 19, col = "steelblue")
abline(v = 30, col = "red", lty = 2)
Figura 2: Relação entre temperatura e ozônio.
Interpretação: os pontos sobem da esquerda para a direita, ou seja, quanto mais quente o dia, maior tende a ser o ozônio. Isso confirma a correlação positiva da equação 3.2 (\(r =\) 0.7). À direita da linha tracejada estão os 20 dias acima de 30 °C filtrados na seção 1.4, quase todos com ozônio acima de 50 ppb.
As referências abaixo foram citadas ao longo das seções deste relatório.