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 deam
evs
. - 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-columndata
que 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!