2017-10-21 3 views
-1

I이 같은 dataframe을 통해 큰 dataframe 각 행 (진짜 훨씬 크다) 다음 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 변수는 차량의 판을 나타냅니다. 데이터 프레임은 첫 번째로 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이 7 개 이상의 백만 행을 포함

따라서 내 방법은 아주 느린 것입니다. 그래서 나는 이것을 할 수있는보다 효율적인 방법이 있는지 묻고 있습니다.

답변

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 

내가 많이 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