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
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.
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.
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
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