标记每个行中的大数据帧经由两个变量

标记每个行中的大数据帧经由两个变量

问题描述:

我有这样一个数据帧(真正的一个大得多):标记每个行中的大数据帧经由两个变量

time<-c(as.POSIXct('2011-11-11 06:00:00'),as.POSIXct('2011-11-11 06:05:00'),as.POSIXct('2011-11-11 07:05:00'), 
      as.POSIXct('2011-11-11 07:10:00'),as.POSIXct('2011-11-11 07:13:00'),as.POSIXct('2011-11-11 07:33:00'), 
      as.POSIXct('2011-11-11 05:05:00'),as.POSIXct('2011-11-11 06:05:00'),as.POSIXct('2011-11-11 06:20:00'), 
      as.POSIXct('2011-11-11 09:05:00')) 
plate<-c('a','a','a','b','c','d','e','e','e','e') 
df<-data.frame(time,plate) 

time变量表示该车辆由视频设备识别的时间。 plate变量代表车辆的盘子。数据帧首先通过plate,其次是time

鉴于此,我想通过标记行来区分每辆车的行程。不同的车辆(plates)肯定代表不同的旅程。对于一辆车,一次行程中识别的时间差应该小于30分钟,否则行应该属于不同的行程。

在我的方式,我将下面的代码做到这一点:

trip<-vector() 
trip[1]<-1 
time_diff<-as.POSIXct('2011-11-11 07:00:00')-as.POSIXct('2011-11-11 06:30:00') 
for (x in 2:nrow(df)) { 
    if (!df$plate[x]==df$plate[x-1]) (trip[x]<-trip[x-1]+1 
) else{if (df$time[x]-df$time[x-1]<time_diff) (trip[x]<-trip[x-1] 
) else (trip[x]<-trip[x-1]+1)} 
} 
df<-cbind(df,trip) 

但是,我df包含超过七个百万行因此我的方法会很慢。所以我问是否有一些更有效的方法来做到这一点。

我建议使用dplyr来做这件事,不过对于7M行,你可能会考虑data.table解决方案,如果这不适合你。

library(dplyr) 

time_diff<-as.POSIXct('2011-11-11 07:00:00')-as.POSIXct('2011-11-11 06:30:00') 

df %>% 
    arrange(time) %>% # it's important, so I reinforce it here 
    group_by(plate) %>% 
    mutate(
    trip = cumsum(c(TRUE, diff(time) > time_diff)) 
) %>% 
    ungroup() 
# # A tibble: 10 × 3 
#     time plate trip 
#     <dttm> <fctr> <int> 
# 1 2011-11-11 06:00:00  a  1 
# 2 2011-11-11 06:05:00  a  1 
# 3 2011-11-11 07:05:00  a  2 
# 4 2011-11-11 07:10:00  b  1 
# 5 2011-11-11 07:13:00  c  1 
# 6 2011-11-11 07:33:00  d  1 
# 7 2011-11-11 05:05:00  e  1 
# 8 2011-11-11 06:05:00  e  2 
# 9 2011-11-11 06:20:00  e  2 
# 10 2011-11-11 09:05:00  e  3 

我更喜欢使用group_by上述解决方案,但如果你想trip必须跨越板独特的,一种技术是处理自己的分组(要求严格的顺序):

df %>% 
    arrange(plate, time) %>% 
    mutate(
    trip = cumsum(plate != lag(plate, default = plate[1]) | c(TRUE, diff(time) > time_diff)) 
) 
#     time plate trip 
# 1 2011-11-11 06:00:00  a 1 
# 2 2011-11-11 06:05:00  a 1 
# 3 2011-11-11 07:05:00  a 2 
# 4 2011-11-11 07:10:00  b 3 
# 5 2011-11-11 07:13:00  c 4 
# 6 2011-11-11 07:33:00  d 5 
# 7 2011-11-11 05:05:00  e 6 
# 8 2011-11-11 06:05:00  e 7 
# 9 2011-11-11 06:20:00  e 7 
# 10 2011-11-11 09:05:00  e 8