Hay una manera más fácil de asegurarse de que los datos del marco de las filas se ordenan de acuerdo a un «target» vector como el que he implementado en el corto ejemplo de abajo?

df <- data.frame(name = letters[1:4], value = c(rep(TRUE, 2), rep(FALSE, 2)))

df
#   name value
# 1    a  TRUE
# 2    b  TRUE
# 3    c FALSE
# 4    d FALSE

target <- c("b", "c", "a", "d")

Esto de alguna manera parece ser un poco demasiado «complicado» para conseguir el trabajo hecho:

idx <- sapply(target, function(x) {
    which(df$name == x)
})
df <- df[idx,]
rownames(df) <- NULL

df 
#   name value
# 1    b  TRUE
# 2    c FALSE
# 3    a  TRUE
# 4    d FALSE
InformationsquelleAutor Rappster | 2012-08-15

3 Comentarios

  1. 203

    Intentar match:

    df <- data.frame(name=letters[1:4], value=c(rep(TRUE, 2), rep(FALSE, 2)))
    target <- c("b", "c", "a", "d")
    df[match(target, df$name),]
    
      name value
    2    b  TRUE
    3    c FALSE
    1    a  TRUE
    4    d FALSE

    Va a trabajar mientras su target contiene exactamente los mismos elementos que df$name, y ni contener valores duplicados.

    De ?match:

    match returns a vector of the positions of (first) matches of its first argument 
    in its second.

    Por lo tanto match encuentra los números de fila que coincide con target‘s elementos y, a continuación, volvemos df en ese orden.

    • Grandes, que es exactamente lo que estaba buscando! Muchas gracias
    • una pregunta, ¿y si la columna que me gustaría para el partido de repetición de los valores? como b,c,a,d,b,c,a,d. Traté de match pero no funciona bien.
    • Me gustaría pensar que tendría que explícitamente asegúrese de que los duplicados se eliminan antes de disparar match(). Lo que viene a la mente es duplicated(), unique() o alguna otra rutina personalizada que «mantiene» los elementos deseados, mientras que tirar a los demás. HTH
    • es una buena solución. Sin embargo, también los cambios de los índices. ¿Cómo puedo también mantenerlos en orden ascendente(1, 2, 3, 4) ?
    • así que ¿qué debo hacer si tengo duplicados en df???
    • no está seguro de que es la forma más limpia, pero sólo con «la base» de las funciones, esto debería funcionar si usted tiene duplicados en el df: df <- data.frame(name=letters[c(1:4, 1:4)], value=c(rep(TRUE, 2), rep(FALSE, 2),rep(TRUE, 2), rep(FALSE, 2) )) target <- c("b", "c", "a", "d") df[order(unlist(sapply(df$name, function(x) which(target == x)))),]

  2. 18

    Este método es un poco diferente, me dio un poco más de flexibilidad que la respuesta anterior.
    Por lo que en un ordenado factor, puede utilizar muy bien en arrange y tal. He utilizado reordenar.el factor de la gdata paquete.

    df <- data.frame(name=letters[1:4], value=c(rep(TRUE, 2), rep(FALSE, 2)))
    target <- c("b", "c", "a", "d")
    
    require(gdata)
    df$name <- reorder.factor(df$name, new.order=target)

    A continuación, utilice el hecho de que es ahora ordenó:

    require(dplyr)
    df %>%
      arrange(name)
        name value
    1    b  TRUE
    2    c FALSE
    3    a  TRUE
    4    d FALSE

    Si quieres volver a la original (alfabético) el pedido, sólo tiene que utilizar as.character() a volver a su estado original.

    • ¿Alguien sabe de un dato.versión de tabla de esto?
    • nombre := factor(nombre, los niveles target=)]. Luego de ver los dos data.table respuestas aquí
  3. 17

    Yo prefiero usar ***_join en dplyr cada vez que necesito para que coincida con los datos. Uno puede intentar para este

    left_join(data.frame(name=target),df,by="name")

    Tenga en cuenta que la entrada para ***_join requieren cucharada o de datos.marco

    • Sí, la *_join funciones en dplyr son muy agradables. Acabar con estas mucho por ahora así
    • En este caso, se recomienda declarar destino como tibble, para evitar que los datos.marco() la conversión de los factores. target <- tibble(name = c("b", "c", "a", "d"))
    • Y con tubo de sintaxis: df %>% right_join(tibble(name = target), by = "name")

Dejar respuesta

Please enter your comment!
Please enter your name here