Pytanie
Używając dplyr
, jak wybrać górne i dolne obserwacje / wiersze zgrupowanych danych w jednej instrukcji?
Dane i przykład
Biorąc pod uwagę ramkę danych
df <- data.frame(id=c(1,1,1,2,2,2,3,3,3),
stopId=c("a","b","c","a","b","c","a","b","c"),
stopSequence=c(1,2,3,3,1,4,3,1,2))
Mogę uzyskać górne i dolne obserwacje z każdej grupy, używając slice
, ale używając dwóch oddzielnych instrukcji:
firstStop <- df %>%
group_by(id) %>%
arrange(stopSequence) %>%
slice(1) %>%
ungroup
lastStop <- df %>%
group_by(id) %>%
arrange(stopSequence) %>%
slice(n()) %>%
ungroup
Czy mogę połączyć te dwa zestawienia statystyk w jedno, które wybiera zarówno górne, jak i dolne obserwacje?
Odpowiedzi:
Prawdopodobnie jest szybszy sposób:
źródło
rownumber() %in% c(1, n())
wyeliminowałoby potrzebę dwukrotnego uruchamiania skanowania wektorów_
? tj.filter(row_number() %in% c(1, n()))
Dla kompletności: możesz podać
slice
wektor indeksów:co daje
źródło
filter
- nie testowałem tego, ale zobacz tutajmtcars[1, ] %>% slice(c(1, n()))
W tym sensie wybór między nimi zależy od tego, co chcesz zwrócić. Spodziewałbym się, że czasy będą bliskie, chyba żen
są bardzo duże (gdzie może być preferowany wycinek), ale też nie testowałem.Nie
dplyr
, ale jest to znacznie bardziej bezpośrednie użyciedata.table
:Bardziej szczegółowe wyjaśnienie:
Aby zapoznać się z podstawami, zajrzyj na wiki Pierwsze kroki
data.table
źródło
df[ df[order(stopSequence), .I[c(1,.N)], keyby=id]$V1 ]
. Widzącid
pojawiają się dwa razy to dziwne dla mnie.setDT
rozmowie. Więcorder
telefon nie ma potrzeby tutaj.df[order(stopSequence), .SD[c(1L,.N)], by = id]
. Zobacz tutajid
. Myślę, żedf[order(stopSequence), .SD[c(1L, .N)], keyby = id]
powinno wystarczyć (z tą różnicą, Minor to rozwiązanie powyższego, że wynik będziekey
edCoś jak:
Z
do
możesz wykonać dowolną liczbę operacji na grupie, ale odpowiedź @ jeremycg jest o wiele bardziej odpowiednia tylko do tego zadania.źródło
slice
, na przykładdf %>% arrange(stopSequence) %>% group_by(id) %>% slice(c(1,n()))
do
przykład tutaj może pomóc innym, gdyslice
nie zadziała (tj. Bardziej złożone operacje na grupie). Jako odpowiedź powinieneś zamieścić swój komentarz (jest najlepszy).Znam określone pytanie
dplyr
. Ale ponieważ inni już opublikowali rozwiązania korzystające z innych pakietów, zdecydowałem się wypróbować również inne pakiety:Pakiet podstawowy:
Tabela danych:
sqldf:
W jednym zapytaniu:
Wynik:
źródło
za pomocą
which.min
iwhich.max
:reper
Jest również znacznie szybszy niż obecnie akceptowana odpowiedź, ponieważ znajdujemy minimalną i maksymalną wartość według grup, zamiast sortować całą kolumnę stopSequence.
źródło
Używając
data.table
:źródło
Inne podejście z lapply i oświadczeniem dplyr. Możemy zastosować dowolną liczbę dowolnych funkcji podsumowujących do tego samego stwierdzenia:
Możesz na przykład zainteresować się wierszami z wartością max stopSequence i zrobić:
źródło
Inną alternatywą bazową R byłoby pierwsze
order
byid
istopSequence
,split
na podstawieid
i dla każdegoid
wybieramy tylko pierwszy i ostatni indeks i podzestawiamy ramkę danych przy użyciu tych indeksów.Lub podobne użycie
by
źródło