Вопрос
Используя dplyr
, как выбрать верхние и нижние наблюдения / строки сгруппированных данных в одном утверждении?
Данные и пример
Учитывая фрейм данных
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))
Я могу получить верхние и нижние наблюдения от каждой группы, используя slice
, но используя две отдельные оценки:
firstStop <- df %>%
group_by(id) %>%
arrange(stopSequence) %>%
slice(1) %>%
ungroup
lastStop <- df %>%
group_by(id) %>%
arrange(stopSequence) %>%
slice(n()) %>%
ungroup
Могу ли я объединить эти два statmenet в один, который выбирает и верхние и нижние наблюдения?
Ответы:
Вероятно, есть более быстрый способ:
источник
rownumber() %in% c(1, n())
избавит от необходимости запускать векторное сканирование дважды_
? то естьfilter(row_number() %in% c(1, n()))
Просто для полноты: вы можете передать
slice
вектор индексов:который дает
источник
filter
- не проверял это, но смотрите здесьmtcars[1, ] %>% slice(c(1, n()))
в этом смысле выбор между ними зависит от того, что вы хотите вернуть. Я ожидаю, что время будет близким, если толькоn
оно не будет очень большим (где срез может быть предпочтительным), но также не проверил.Нет
dplyr
, но это гораздо более прямое использованиеdata.table
:Более подробное объяснение:
Обязательно ознакомьтесь с вики « Приступая к работе» , чтобы узнать
data.table
основыисточник
df[ df[order(stopSequence), .I[c(1,.N)], keyby=id]$V1 ]
. Видетьid
дважды появляется странно для меня.setDT
вызове. Так чтоorder
звонить здесь не нужно.df[order(stopSequence), .SD[c(1L,.N)], by = id]
. Смотрите здесьid
. Я думаю , чтоdf[order(stopSequence), .SD[c(1L, .N)], keyby = id]
следует сделать трюк (с разницей в незначительной к решению выше , что результат будетkey
эдЧто-то вроде:
С ним
do
вы можете выполнять любое количество операций над группой, но ответ @ jeremycg более подходит для этой задачи.источник
slice
, какdf %>% arrange(stopSequence) %>% group_by(id) %>% slice(c(1,n()))
do
приведенный здесь пример может помочь другим, когдаslice
не будет работать (т.е. более сложные операции в группе). И вы должны опубликовать свой комментарий в качестве ответа (это лучший).Я знаю заданный вопрос
dplyr
. Но, поскольку другие уже опубликовали решения с использованием других пакетов, я решил попробовать и другие пакеты:Базовый пакет:
Таблица данных:
sqldf:
В одном запросе:
Вывод:
источник
используя
which.min
иwhich.max
:эталонный тест
Это также намного быстрее, чем текущий принятый ответ, потому что мы находим минимальное и максимальное значение по группам, а не сортируем весь столбец stopSequence.
источник
Использование
data.table
:источник
Другой подход с lapply и заявлением dplyr. Мы можем применить произвольное число любых итоговых функций к одному и тому же утверждению:
Например, вы можете быть заинтересованы в строках со значением max stopSequence и сделать:
источник
Другая база R Альтернатива будет первым
order
наid
иstopSequence
,split
их на основеid
и для каждыхid
мы выбираем только первый и последний индекс и подмножество в dataframe с помощью этих индексов.Или аналогично, используя
by
источник