Jak wybrać wiersze z maksymalnymi wartościami w każdej grupie za pomocą dplyr? [duplikat]
Chciałbym wybrać wiersz z maksymalną wartością w każdej grupie z dplyr.
Najpierw generuję losowe DANE, aby pokazać moje pytanie
set.seed(1)
df <- expand.grid(list(A = 1:5, B = 1:5, C = 1:5))
df$value <- runif(nrow(df))
W plyr mogę użyć niestandardowej funkcji, aby wybrać ten wiersz.
library(plyr)
ddply(df, .(A, B), function(x) x[which.max(x$value),])
W dplyr, używam tego kodu, aby uzyskać maksymalną wartość, ale nie wiersze z maksymalną wartością (kolumna C w tym przypadku).
library(dplyr)
df %>% group_by(A, B) %>%
summarise(max = max(value))
Jak mógłbym to osiągnąć? Dzięki za wszelkie sugestia.
sessionInfo()
R version 3.1.0 (2014-04-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C
[5] LC_TIME=English_Australia.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] dplyr_0.2 plyr_1.8.1
loaded via a namespace (and not attached):
[1] assertthat_0.1.0.99 parallel_3.1.0 Rcpp_0.11.1
[4] tools_3.1.0
6 answers
Spróbuj tego:
result <- df %>%
group_by(A, B) %>%
filter(value == max(value)) %>%
arrange(A,B,C)
Wydaje się działać:
identical(
as.data.frame(result),
ddply(df, .(A, B), function(x) x[which.max(x$value),])
)
#[1] TRUE
Jak zaznaczono w komentarzach, slice
może być preferowane tutaj zgodnie z @RoyalITS' odpowiedź poniżej Jeśli chcesz tylko 1 wiersz na Grupę. Ta odpowiedź zwróci wiele wierszy, jeśli istnieje wiele z identyczną wartością maksymalną.
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
2020-06-22 21:49:54
Możesz użyć top_n
df %>% group_by(A, B) %>% top_n(n=1)
Zostanie to uszeregowane według ostatniej kolumny (value
) i zwróci górne n=1
wiersze.
Obecnie nie można zmienić tej wartości domyślnej bez powodowania błędu (Zobacz https://github.com/hadley/dplyr/issues/426 )
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
2014-06-16 06:14:51
df %>% group_by(A,B) %>% slice(which.max(value))
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-02-24 16:40:23
To bardziej wyraziste rozwiązanie zapewnia większą kontrolę nad tym, co dzieje się w przypadku zduplikowanej wartości maksymalnej (w tym przykładzie, będzie pobierał jeden z odpowiadających wierszy losowo)
library(dplyr)
df %>% group_by(A, B) %>%
mutate(the_rank = rank(-value, ties.method = "random")) %>%
filter(the_rank == 1) %>% select(-the_rank)
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-07-18 07:59:37
Bardziej ogólnie, myślę, że możesz chcieć uzyskać "górę" wierszy, które są posortowane w danej grupie.
W przypadku, gdy pojedyncza wartość jest max ' d out, zasadniczo posortowano tylko jedną kolumnę. Jednak często przydatne jest hierarchiczne sortowanie według wielu kolumn (na przykład: kolumna daty i Kolumna godziny dnia).
# Answering the question of getting row with max "value".
df %>%
# Within each grouping of A and B values.
group_by( A, B) %>%
# Sort rows in descending order by "value" column.
arrange( desc(value) ) %>%
# Pick the top 1 value
slice(1) %>%
# Remember to ungroup in case you want to do further work without grouping.
ungroup()
# Answering an extension of the question of
# getting row with the max value of the lowest "C".
df %>%
# Within each grouping of A and B values.
group_by( A, B) %>%
# Sort rows in ascending order by C, and then within that by
# descending order by "value" column.
arrange( C, desc(value) ) %>%
# Pick the one top row based on the sort
slice(1) %>%
# Remember to ungroup in case you want to do further work without grouping.
ungroup()
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
2019-01-16 19:06:22
Dla mnie pomogło zliczyć liczbę wartości na Grupę. Skopiuj tabelę zliczania do nowego obiektu. Następnie filtruj dla max grupy na podstawie pierwszej charakterystyki grupowania. Na przykład:
count_table <- df %>%
group_by(A, B) %>%
count() %>%
arrange(A, desc(n))
count_table %>%
group_by(A) %>%
filter(n == max(n))
Lub
count_table %>%
group_by(A) %>%
top_n(1, n)
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
2019-02-01 14:39:13