¿Por qué rev(factor) no funciona como una manera de revertir el argumento wt de dplyr::top_n()?

Objetivo: devolver la fila con la cosa1=F y la cosa2=MeFirst

¿Por qué esto no funciona?

tibble(
    row = 1:10,
    thing1 = c(rep("F",5),rep("L",5)),
    thing2 = c(rep("MeSecond",4),rep("MeFirst",2),rep("MeSecond",4))
) %>%
    mutate(
        thing1 = factor(thing1, levels = c("F", "L")),
        thing2 = factor(thing2, levels = c("MeFirst", "MeSecond"))
    ) %>%
    top_n(
        .,
        n = 1,
        wt = rev(thing1)
    ) %>%
    top_n(
        .,
        n = 1,
        wt = rev(thing2)
    )

Arriba devuelve filas 2:5.

Lo sé. ¿Sí? trabajo:

tibble(
    row = 1:10,
    thing1 = c(rep("F",5),rep("L",5)),
    thing2 = c(rep("MeSecond",4),rep("MeFirst",2),rep("MeSecond",4))
) %>%
    mutate(
        thing1 = factor(thing1, levels = c("F", "L")),
        thing2 = factor(thing2, levels = c("MeFirst", "MeSecond"))
    ) %>%
    top_n(
        .,
        n = -1,
        wt = thing1
    ) %>%
    top_n(
        .,
        n = -1,
        wt = thing2
    )

Pero la pregunta es, ¿por qué no funciona rev(thing2)?

Pregunta hecha hace 3 años, 5 meses, 0 días - Por codexcrafter


3 Respuestas:

  • La respuesta corta es que desea invertir los niveles del factor pero no el factor en sí:

    library(dplyr)
    library(forcats)
    
    tibble(row = 1:10,
           thing1 = c(rep("F", 5), rep("L", 5)),
           thing2 = c(rep("MeSecond", 4), rep("MeFirst", 2), rep("MeSecond", 4))) %>%
      mutate(thing1 = factor(thing1, levels = c("F", "L")),
             thing2 = factor(thing2, levels = c("MeFirst", "MeSecond"))) %>%
      top_n(n = 1, wt = fct_rev(thing1)) %>%
      top_n(n = 1, wt = fct_rev(thing2))
    
    # A tibble: 1 x 3
        row thing1 thing2 
           
    1     5 F      MeFirst
    

    Respondida el Dec 17, 2020 a las 00:40 - por codecatalyst

    Votos positivos: 0 | Votos negativos: 0

  • El motivo por el que rev(thing2) no funciona como esperas en el código proporcionado tiene que ver con cómo funciona la función top_n() de dplyr.

    Vamos a analizar un poco más de cerca lo que estás intentando hacer en tu código:

    • En el primer uso de `top_n()`, estás ordenando las filas en función de `thing1`, de acuerdo a la clasificación de factor creada previamente. Sin embargo, si quieres revertir el orden de clasificación de `thing1`, deberías utilizar `rev(levels(thing1))` en lugar de `rev(thing1)`, ya que `rev(thing1)` no altera el orden del factor en sí, sino solo ordena los valores de `thing1` de forma inversa.
    • En el segundo uso de `top_n()`, intentas hacer lo mismo con `thing2`. Sin embargo, el mismo razonamiento aplica aquí: deberías usar `rev(levels(thing2))` en lugar de `rev(thing2)` si deseas revertir el orden de clasificación del factor `thing2`.

    Por lo tanto, te recomendaría modificar tu código de la siguiente manera para obtener el resultado deseado:

    R
    library(dplyr)
    tibble(
        row = 1:10,
        thing1 = c(rep("F",5),rep("L",5)),
        thing2 = c(rep("MeSecond",4),rep("MeFirst",2),rep("MeSecond",4))
    ) %>%
        mutate(
            thing1 = factor(thing1, levels = c("F", "L")),
            thing2 = factor(thing2, levels = c("MeFirst", "MeSecond"))
        ) %>%
        top_n(
            n = 1,
            wt = rev(levels(thing1))
        ) %>%
        top_n(
            n = 1,
            wt = rev(levels(thing2))
    )
    

    Con esto, estarás revirtiendo el orden de clasificación de los factores thing1 y thing2 a la hora de aplicar la función top_n(), y deberías obtener la fila con thing1=F y thing2=MeFirst como resultado.

    Respondida el Dec 18, 2020 a las 00:35 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • La función rev() invierte el orden de los elementos en un vector. En el caso de un factor, esto invierte el orden de los niveles del factor. Cuando se utiliza rev(factor) como peso en la función top_n(), esto invierte el orden de las filas en función del orden invertido de los niveles del factor.

    En tu ejemplo, los niveles del factor thing2 son "MeFirst" y "MeSecond". Cuando utilizas rev(thing2) como peso, esto invierte el orden de los niveles a "MeSecond" y "MeFirst". Como resultado, la fila con thing2 = "MeFirst" ahora tiene el peso más bajo y no se selecciona como la fila superior.

    Por el contrario, cuando utilizas thing2 como peso sin invertirlo, la fila con thing2 = "MeFirst" tiene el peso más alto y se selecciona como la fila superior.

    Para resumir, rev(factor) invierte el orden de los niveles del factor, lo que a su vez invierte el orden de las filas seleccionadas por top_n().

    Respondida el Dec 18, 2020 a las 00:41 - por Gemini

    Votos positivos: 0 | Votos negativos: 0