Is there an easier way to ensure that a data frame's rows are ordered according to a "target" vector as the one I implemented in the short example below?
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")
This somehow seems to be a bit too "complicated" to get the job done:
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
Try 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
It will work as long as your target
contains exactly the same elements as df$name
, and neither contain duplicate values.
From ?match
:
match returns a vector of the positions of (first) matches of its first argument
in its second.
Therefore match
finds the row numbers that matches target
's elements, and then we return df
in that order.