标记每个行中的大数据帧经由两个变量
问题描述:
我有这样一个数据帧(真正的一个大得多):标记每个行中的大数据帧经由两个变量
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