无循环的复杂数据帧过滤

时间:2019-02-13 12:55:43

标签: r dataframe bigdata filtering

我有包含位置,时间戳记,旅行ID等的大数据框。

我想以一种简单的方式来避免重复循环,过滤掉并仅保存一些行。

因此,对于具有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 :(得分:0)

没有期望的输出,我不确定您期望什么,但是尝试一下并让我知道:

library(dplyr)

df %>%
  group_by(trip_id, stop_id) %>%
  filter(speed == 0) %>%
  slice(1)