Hoje estava fazendo uma análise exploratória e precisava estudar os quartis de uma variável contínua. A solução usando o tidyverse é tão elegante que valeu um post no blog.
Usaremos os pacotes tibble, dplyr, tidyr e purrr. Caso você não tenha qualquer um deles instalado, basta rodar os códigos abaixo.
install.packages(tibble)
install.packages(dplyr)
install.packages(tidyr)
install.packages(purrr)
Nesse exemplo, usamos a famosa base mtcars:
tab <- mtcars |>
dplyr::group_by(am, vs) |>
tidyr::nest() |>
dplyr::mutate(
quartis = purrr::map(data, ~ tibble::enframe(quantile(.x$mpg, 1:4 / 4)))
) |>
tidyr::unnest(quartis) |>
tidyr::pivot_wider(
names_from = name,
values_from = value
) |>
dplyr::select(-data)
tab
## # A tibble: 4 × 6
## # Groups: am, vs [4]
## vs am `25%` `50%` `75%` `100%`
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0 1 16.8 20.4 21 26
## 2 1 1 25.0 30.4 31.4 33.9
## 3 1 0 18.6 21.4 22.2 24.4
## 4 0 0 14.0 15.2 16.6 19.2
- A função
dplyr::group_by()faz um grupo para cada combinação deamevs. - A função
tidyr::nest()guarda os dados de cada grupo numa list-column chamadadata. - A função
purrr::map()aplica elegantemente a funçãoquantile()para cada grupo de datas, sendo ajudada pela funçãotibble::enframe(), que coloca o resultado dequantile()em umatibble. - A função
tidyr::unnest()coloca os resultados de volta em colunas-vetores. - Terminamos com
tidyr::pivot_wider()para espalhar os quartis nas colunas e a funçãodplyr::select()para remover a list-columndataque não precisamos mais.
O resultado pode ser jogado diretamente numa tabela:
knitr::kable(tab) |>
kableExtra::kable_styling()
| vs | am | 25% | 50% | 75% | 100% |
|---|---|---|---|---|---|
| 0 | 1 | 16.775 | 20.35 | 21.000 | 26.0 |
| 1 | 1 | 25.050 | 30.40 | 31.400 | 33.9 |
| 1 | 0 | 18.650 | 21.40 | 22.150 | 24.4 |
| 0 | 0 | 14.050 | 15.20 | 16.625 | 19.2 |
É possível mudar esse código para ter outras medidas-resumo, por exemplo. Para isso, podemos usar a função summary(), por exemplo, ou criar nossa própria função.
mtcars |>
dplyr::group_by(am, vs) |>
tidyr::nest() |>
dplyr::mutate(
s = purrr::map(data, ~tibble::enframe(summary(.x$mpg))),
s = purrr::map(s, ~ .x |> dplyr::mutate(value = as.numeric(value)))
) |>
dplyr::select(vs, am, s) |>
tidyr::unnest(s) |>
tidyr::pivot_wider(names_from = name, values_from = value) |>
knitr::kable() |>
kableExtra::kable_styling()
| vs | am | Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 15.0 | 16.775 | 20.35 | 19.75000 | 21.000 | 26.0 |
| 1 | 1 | 21.4 | 25.050 | 30.40 | 28.37143 | 31.400 | 33.9 |
| 1 | 0 | 17.8 | 18.650 | 21.40 | 20.74286 | 22.150 | 24.4 |
| 0 | 0 | 10.4 | 14.050 | 15.20 | 15.05000 | 16.625 | 19.2 |
Como você resolveria essa task? Escreva nos comentários!