是否有一种更简单的方法来确保数据帧的行按照“目标”向量进行排序,就像我在下面的简短示例中实现的那样?

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")

这似乎有点太“复杂”了,无法完成工作:

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

当前回答

尝试匹配:

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

只要你的目标包含与df$name完全相同的元素,并且都不包含重复的值,它就可以工作。

来自哪里?匹配:

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

因此match查找与目标元素匹配的行号,然后按此顺序返回df。

其他回答

尝试匹配:

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

只要你的目标包含与df$name完全相同的元素,并且都不包含重复的值,它就可以工作。

来自哪里?匹配:

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

因此match查找与目标元素匹配的行号,然后按此顺序返回df。

这个方法有点不同,它比之前的答案提供了更多的灵活性。 通过使它成为一个有序因子,你可以很好地在排列中使用它。我用的是重新排序。来自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)

接下来,利用它现在是有序的事实:

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

如果你想回到原来的(字母)顺序,只需使用as.character()让它回到原来的状态。

当需要匹配数据时,我更喜欢在dplyr中使用***_join。一个可能的尝试

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

注意,***_join的输入需要tbls或data.frame

我们可以根据目标来调整因子水平,并将其用于排列

library(dplyr)
df %>% arrange(factor(name, levels = target))

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

或者点餐,切片食用

df %>% slice(order(factor(name, levels = target)))

如果您不想使用任何库,并且您的数据中有重复出现的情况,您也可以使用sapply。

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