Uporządkuj rzędy ramek danych według wektora o określonym porządku

Czy istnieje łatwiejszy sposób, aby zapewnić, że wiersze ramki danych są uporządkowane według wektora "docelowego", jak ten, który zaimplementowałem w krótkim przykładzie poniżej?

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

To wydaje się być trochę zbyt "skomplikowane", aby wykonać zadanie:

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
Author: Henrik, 2012-08-16

3 answers

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

Będzie działać tak długo, jak Twój target zawiera dokładnie te same elementy, co df$name, A żaden z nich nie zawiera zduplikowanych wartości.

From ?match:

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

Dlatego match znajduje liczby wierszy pasujące do elementów target, a następnie zwracamy df w tej kolejności.

 169
Author: Edward,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-15 21:13:22

Ta metoda jest nieco inna, zapewniła mi nieco większą elastyczność niż poprzednia odpowiedź. Zmieniając go w czynnik uporządkowany, można go ładnie wykorzystać w {[2] } i takich. Zmieniłem kolejność.Współczynnik z pakietu 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)

Następnie użyj faktu, że jest teraz uporządkowany:

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

Jeśli chcesz wrócić do oryginalnego (alfabetycznego) porządku, po prostu użyj as.character(), aby przywrócić go do pierwotnego stanu.

 15
Author: MattV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-26 11:11:04

Wolę używać ***_join w dplyr, gdy potrzebuję dopasować dane. Jedna z możliwych prób tego

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

Zauważ, że wejście dla ***_join wymaga tbls lub danych.frame

 11
Author: Lerong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-23 03:30:00