Сложная фильтрация фрейма данных без циклов - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть большой фрейм данных с позициями, отметками времени, идентификаторами поездок и т. Д.

Я бы хотел простым способом избежать двойных циклов, отфильтровать и сохранить только некоторые строки.

Таким образом, для всех строк, имеющих одинаковую комбинацию trip_id и stop_id, я хочу сохранить строку, в которой скорость сначала была равна нулю.Либо возьмите минимальную временную метку, где скорость равна нулю, либо просто просто в первый раз, когда скорость равна нулю, так как кадр упорядочен по временной метке.

Итак, в приведенном ниже примере я хотел бы найти три верхние строки (в реальном кадре данных гораздо больше строк) и просто сохранить вторую строку, где скорость сначала была равна нулю.

Есть ли способ сделать это без каких-либо циклов?

trip_id.x          stop_id          latitude.x         longitude.x        bearing speed  timestamp       vehicle id
55700000048910944 9022005000050006  58.416879999999999 15.624510000000001      30   0.2 1541399400 9031005990005424
55700000048910944 9022005000050006  58.416879999999999 15.624510000000001       0     0 1541399401 9031005990005424
55700000048910944 9022005000050006  58.416879999999999 15.624510000000001       0     0 1541399402 9031005990005424
55700000048910300 9022005000050006  58.416879999999999 15.624510000000001      30   0.5 1541400000 9031005990005424

Редактировать: Вот dput () более длинного теста с более простым форматом данных, которые у меня есть:

    structure(list(trip_id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3), stop_id = c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 1, 
1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 
3, 3), speed = c(5, 0, 0, 5, 2, 0, 0, 2, 4, 0, 0, 4, 5, 0, 0, 
5, 2, 0, 0, 2, 4, 0, 0, 4, 5, 0, 0, 5, 2, 0, 0, 2, 4, 0, 0, 4
), timestamp = c(1, 2, 3, 4, 101, 102, 103, 104, 201, 202, 203, 
204, 301, 302, 303, 304, 401, 402, 403, 404, 501, 502, 503, 504, 
601, 602, 603, 604, 701, 702, 703, 704, 801, 802, 803, 804)), row.names = c(NA, 
-36L), class = c("tbl_df", "tbl", "data.frame"))

И требуемый результат:

    structure(list(trip_id = c(1, 1, 2, 2, 2, 3, 3, 3), stop_id = c(1, 
3, 1, 2, 3, 1, 2, 3), speed = c(0, 0, 0, 0, 0, 0, 0, 0), timestamp = c(2, 
202, 302, 402, 502, 602, 702, 802)), row.names = c(NA, -8L), class = c("tbl_df", 
"tbl", "data.frame"))

Редактировать: Попытка изменить код, чтобы иметь условия в нем.Пробовал с case_when и если но не могу заставить его работать:

df_arrival_z <- df %>%
  group_by(trip_id, stop_id) %>%
  filter(speed == 0)
  # Check if there is any rows where speed is zero
  if (nrow(filter(speed == 0)) > 0){
    # Take the first row if there is rows with zero
    filter(speed == 0) %>% slice(1)
  }
  if (nrow(filter(speed == 0)) == 0){
    # Take the middle point if there is no rows with speed = 0
    slice(nrow%/%2)
  }

1 Ответ

0 голосов
/ 13 февраля 2019

Без желаемого результата я не могу быть уверен, что вы ожидаете, но попробуйте это и дайте мне знать:

library(dplyr)

df %>%
  group_by(trip_id, stop_id) %>%
  filter(speed == 0) %>%
  slice(1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...