Reorganiza un dataframe para poder seleccionar el valor mínimo y máximo para cada grupo.
Tengo un dataframe que se ve así:
library(tidyverse)
df <- tibble::tribble(
~id, ~name, ~type, ~value,
1, "aaaa", "car", 2.67,
1, "aaaa", "moto", 2,
2, "bbbb", "bike", 3.67,
4, "cccc", "skate", 2.75,
6, "dddd", "snowboard", 4.33,
7, "eeee", "scooter", 2.8,
7, "eeee", "car", 2.33,
7, "eeee", "ski", 2.5,
8, "ffff", "boat", 3,
8, "ffff", "scooter", 2.8
)
Me gustaría obtener para cada id
y name
:
- El mejor tipo basado en el
value
(es decir,max(value)
) - El peor tipo basado en el
value
(es decir,min(value)
) - Cuando solo hay una fila para cada combinación de
id
/name
, me gustaría que el valor se coloque en la columna~best
, mientras que-
debe aparecer en~worst
.
Resultando en:
df_final <- tibble::tribble(
~id, ~name, ~best, ~worst,
1, "aaaa", "car", "moto",
2, "bbbb", "bike", "-",
4, "cccc", "skate", "-",
6, "dddd", "snowboard", "-",
7, "eeee", "scooter", "car",
8, "ffff", "boat", "scooter"
)
Intenté usar slice_max()
, ¡pero no puedo entender cómo colocar el type
en las columnas ~best
/ ~worst
!
davy.ai
Para lograr estos resultados, puedes agrupar el
df
original porid
yname
y luego usarslice_max()
yslice_min()
para obtener las filas con los valores máximos y mínimos para cada grupo. Luego puedes usartidyr::pivot_wider()
para remodelar el data frame con las columnasbest
yworst
. Finalmente, puedes usardplyr::mutate()
para reemplazar los valores faltantes en la columnaworst
con-
.Aquí tienes el código para hacer esto:
{r}
df_final <- df %>%
group_by(id, name) %>%
slice_max(value, n = 1) %>%
mutate(best = type) %>%
select(-value, -type) %>%
slice_min(value, n = 1) %>%
mutate(worst = type) %>%
ungroup() %>%
select(-value, -type) %>%
tidyr::pivot_wider(names_from = type, values_from = c(best, worst), values_fill = list(worst = "-")) %>%
dplyr::mutate(worst = if_else(is.na(worst), "-", worst))
Ten en cuenta que
slice_max()
yslice_min()
se utilizan por separado parabest
yworst
, en lugar de hacer ambos en una sola llamada, ya que queremos mantener la columnatype
parabest
pero no paraworst
. También utilizamosvalues_fill
enpivot_wider()
para reemplazar los valores faltantes en la columnaworst
con-
, yif_else()
para reemplazar los valores faltantes restantes con-
.