Упорядочить строки фрейма данных по вектору с определенным порядком
есть ли более простой способ гарантировать, что строки фрейма данных упорядочены в соответствии с" целевым " вектором, как тот, который я реализовал в коротком примере ниже?
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
3 ответов
попробовать 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
он будет работать до тех пор, как ваш target
содержит точно такие же элементы, как df$name
, и ни один из них не содержит повторяющихся значений.
С ?match
:
match returns a vector of the positions of (first) matches of its first argument
in its second.
match
находит номера строк, что соответствует target
элементы, а затем мы возвращаемся df
в таком порядке.этот метод немного отличается, он дал мне немного больше гибкости, чем предыдущий ответ.
Сделав его упорядоченным фактором, вы можете использовать его красиво в arrange
и такие. Я переупорядочить.фактор из .
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()
, чтобы вернуть его в исходное состояние.
Я предпочитаю использовать ***_join
на dplyr
когда мне нужно сопоставить данные. Одна возможная попытка для этого
left_join(data.frame(name=target),df,by="name")
обратите внимание, что вход для ***_join
требуется tbls или данные.кадр