2017-10-21 6 views
-1

私はこのようなデータフレームを有する介し大型データフレームの各行(実一つがはるかに大きい):time変数は、車両がビデオ装置によって識別されることが時間を表しマーク二つの変数

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) 

plate変数は車両のプレートを表します。データフレームは、まず第1にplate、第2にtimeで整列されています。

これを踏まえて、各車両のトリップを行に印を付けて分けたいと思います。異なる車両(plates)は確かに異なる旅行を表します。 1台の車両では、1回の旅行で特定された時間差は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は、このように私の方法は非常に遅くなり700万人以上の行が含まれています。だから私はこれを行うより効率的な方法がいくつかあるかどうか尋ねています。

答えて

2

これは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 

1つの技術は、(厳密な順序付けを必要とする)自分でグループ分けを処理することです、私はあまり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