es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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:

  1. El mejor tipo basado en el value (es decir, max(value))
  2. El peor tipo basado en el value (es decir, min(value))
  3. 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!

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para lograr estos resultados, puedes agrupar el df original por id y name y luego usar slice_max() y slice_min() para obtener las filas con los valores máximos y mínimos para cada grupo. Luego puedes usar tidyr::pivot_wider() para remodelar el data frame con las columnas best y worst. Finalmente, puedes usar dplyr::mutate() para reemplazar los valores faltantes en la columna worst 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() y slice_min() se utilizan por separado para best y worst, en lugar de hacer ambos en una sola llamada, ya que queremos mantener la columna type para best pero no para worst. También utilizamos values_fill en pivot_wider() para reemplazar los valores faltantes en la columna worst con -, y if_else() para reemplazar los valores faltantes restantes con -.

Comments are closed.