Выберите первую и последнюю строку из сгруппированных данных

Вопрос

Используя 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 % group_by(id) %>% arrange(stopSequence) %>% slice(1) %>% ungroup lastStop % group_by(id) %>% arrange(stopSequence) %>% slice(n()) %>% ungroup 

Могу ли я объединить эти два statmenets в один, который выбирает как верхние, так и нижние наблюдения?

Вероятно, существует более быстрый способ:

 df %>% group_by(id) %>% arrange(stopSequence) %>% filter(row_number()==1 | row_number()==n()) 

Просто для полноты: вы можете передать slice вектора индексов:

 df %>% arrange(stopSequence) %>% group_by(id) %>% slice(c(1,n())) 

который дает

  id stopId stopSequence 1 1 a 1 2 1 c 3 3 2 b 1 4 2 c 4 5 3 b 1 6 3 a 3 

Не dplyr , но гораздо более прямое использование data.table :

 library(data.table) setDT(df) df[ df[order(id, stopSequence), .I[c(1L,.N)], by=id]$V1 ] # id stopId stopSequence # 1: 1 a 1 # 2: 1 c 3 # 3: 2 b 1 # 4: 2 c 4 # 5: 3 b 1 # 6: 3 a 3 

Более подробное объяснение:

 # 1) get row numbers of first/last observations from each group # * basically, we sort the table by id/stopSequence, then, # grouping by id, name the row numbers of the first/last # observations for each id; since this operation produces # a data.table # * .I is data.table shorthand for the row number # * here, to be maximally explicit, I've named the variable V1 # as row_num to give other readers of my code a clearer # understanding of what operation is producing what variable first_last = df[order(id, stopSequence), .(row_num = .I[c(1L,.N)]), by=id] idx = first_last$row_num # 2) extract rows by number df[idx] 

Обязательно ознакомьтесь с Вики- data.table Getting Started для получения data.table

Что-то вроде:

 library(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)) first_last <- function(x) { bind_rows(slice(x, 1), slice(x, n())) } df %>% group_by(id) %>% arrange(stopSequence) %>% do(first_last(.)) %>% ungroup ## Source: local data frame [6 x 3] ## ## id stopId stopSequence ## 1 1 a 1 ## 2 1 c 3 ## 3 2 b 1 ## 4 2 c 4 ## 5 3 b 1 ## 6 3 a 3 

С помощью вы можете в значительной степени выполнять любое количество операций в группе, но ответ @ jeremycg более подходит для этой задачи.

Я знаю вопрос, заданный dplyr . Но, поскольку другие уже размещали решения с использованием других пакетов, я решил пойти и с другими пакетами:

Базовый пакет:

 df <- df[with(df, order(id, stopSequence, stopId)), ] merge(df[!duplicated(df$id), ], df[!duplicated(df$id, fromLast = TRUE), ], all = TRUE) 

Таблица данных:

 df <- setDT(df) df[order(id, stopSequence)][, .SD[c(1,.N)], by=id] 

sqldf:

 library(sqldf) min <- sqldf("SELECT id, stopId, min(stopSequence) AS StopSequence FROM df GROUP BY id ORDER BY id, StopSequence, stopId") max <- sqldf("SELECT id, stopId, max(stopSequence) AS StopSequence FROM df GROUP BY id ORDER BY id, StopSequence, stopId") sqldf("SELECT * FROM min UNION SELECT * FROM max") 

В одном запросе:

 sqldf("SELECT * FROM (SELECT id, stopId, min(stopSequence) AS StopSequence FROM df GROUP BY id ORDER BY id, StopSequence, stopId) UNION SELECT * FROM (SELECT id, stopId, max(stopSequence) AS StopSequence FROM df GROUP BY id ORDER BY id, StopSequence, stopId)") 

Вывод:

  id stopId StopSequence 1 1 a 1 2 1 c 3 3 2 b 1 4 2 c 4 5 3 a 3 6 3 b 1 
  • Сплит скрипка с ggplot2
  • Увеличить количество тиков оси
  • Локальная долгота Координаты с кодом состояния в R
  • Эффективный способ фильтрации одного фрейма данных по диапазонам в другом
  • Может ли Sweave автоматически создавать много PDF-файлов?
  • Как отключить научную нотацию?
  • Что-то не так с использованием T & F вместо TRUE & FALSE?
  • R с укороченным процентом штрихового графика с процентом двоичного коэффициента и меток (с ggplot)
  • dplyr на data.table, я действительно использую data.table?
  • скептически отслеживает, как очистить данные с этого сайта (используя R)
  • как кумулятивно добавить значения в один вектор из R
  • Давайте будем гением компьютера.