Ordenar filas de marcos de datos según el vector con orden específico

¿Hay alguna manera más fácil de garantizar que las filas de un dataframe se ordenen de acuerdo con un vector “objective” como el que implementé en el siguiente ejemplo?

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 demasiado “complicado” para hacer el trabajo:

 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 

Pruebe la 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 

Funcionará siempre que su target contenga exactamente los mismos elementos que df$name , y ninguno contenga valores duplicados.

Desde ?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 coinciden con los elementos del target , y luego devolvemos df en ese orden.

Este método es un poco diferente, me brindó un poco más de flexibilidad que la respuesta anterior. Al convertirlo en un factor ordenado, puede usarlo bien en los arrange y demás. Usé gdata paquete gdata .

 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, use el hecho de que ahora está ordenado:

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

Si desea volver al orden original (alfabético), simplemente use as.character() para volver al estado original.

Prefiero usar ***_join en dplyr cada vez que necesito emparejar datos. Una posible prueba para esto

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

Tenga en cuenta que la entrada para ***_join requiere tbls o data.frame