2017-09-27 4 views
3

자전거의 궤적을 다른 스테이션으로 추적하는 샘플 데이터 세트가 있습니다. 자전거이 경우, difftime()와 특정 역에 남아 내 목표는 간격을 찾을 수 있습니다, 역선행 행의 데이터 참조

> test 
    bikeid start_station   starttime end_station    endtime 
1  1    A 2017-09-25 01:00:00   B 2017-09-25 01:30:00 
2  1    B 2017-09-25 07:30:00   C 2017-09-25 08:00:00 
3  1    C 2017-09-25 10:00:00   A 2017-09-25 10:30:00 
4  1    A 2017-09-25 13:00:00   C 2017-09-25 13:30:00 
5  1    C 2017-09-25 15:30:00   B 2017-09-25 16:00:00 
6  1    B 2017-09-25 18:00:00   B 2017-09-25 18:30:00 
7  1    B 2017-09-25 19:00:00   A 2017-09-25 19:30:00 
8  1    А 2017-09-25 20:00:00   B 2017-09-25 20:30:00 
9  1    C 2017-09-25 22:00:00   C 2017-09-25 22:30:00 
10  1    B 2017-09-25 23:00:00   C 2017-09-25 23:30:00 

때때로, 자전거들이 종료 같은 역에서 시작하지 않는 B.,이 경우 무시해야합니다. 위의 데이터 세트에서 01:30:0007:30:00 사이에 360 분이 경과했으며 120 분이 16:00:0018:00:00 사이에서 경과했으며 18:30:0019:00:00 사이에 30 분이 경과 한 것을 볼 수 있습니다. 자전거가 끝난 동일한 역에서 자전거가 시작되지 않으므로 행 8과 10은 무시됩니다. 따라서, 출력 벡터가 있어야한다 :

[1] 360 120 30 

원하는 출력 생성하지 않습니다 사용하여 다음 코드 :

sapply(test$starttime[test$end_station == "B"], function(x, et) difftime(et[x < et][1], x, units = "mins"), et = test$endtime[test$start_station == "B"]) 

하나의 계정에 다음 행을 걸릴 것 어떻게하고 difftime()을 계산하는 경우에만 end_station 및 다음 행의 start_station은 동일합니까? dplyrlead()을 사용 하시겠습니까? 자전거는 대기 상태에서 주문을 위해 다시 전체에 ...

library(data.table) 

mtest = melt(setDT(test), id="bikeid", 
    meas = patterns("_station", "time"), 
    variable.name = "event", 
    value.name = c("station", "time")) 
mtest[.(factor(1:2), c("start", "end")), on=.(event), event := i.V2] 
setkey(mtest, bikeid, time) 

as suggested 마지막으로 재편

> dput(test) 
structure(list(bikeid = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), start_station = c("A", 
"B", "C", "A", "C", "B", "B", "А", "C", "B"), starttime = structure(c(1506315600, 
1506339000, 1506348000, 1506358800, 1506367800, 1506376800, 1506380400, 
1506384000, 1506391200, 1506394800), class = c("POSIXct", "POSIXt" 
), tzone = ""), end_station = c("B", "C", "A", "C", "B", "B", 
"A", "B", "C", "C"), endtime = structure(c(1506317400, 1506340800, 
1506349800, 1506360600, 1506369600, 1506378600, 1506382200, 1506385800, 
1506393000, 1506396600), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = c("bikeid", 
"start_station", "starttime", "end_station", "endtime"), row.names = c(NA, 
-10L), class = "data.frame") 

답변

5

.. : 어떤 제안은 여기

을 주시면 감사하겠습니다 샘플 데이터입니다

idleDT = dcast(mtest[-c(1,.N)][, g := rep(1:.N, each=2, length.out=.N)], 
    g ~ rowid(g), value.var=c("station", "time")) 

    g station_1 station_2    time_1    time_2 
1: 1   B   B 2017-09-25 01:30:00 2017-09-25 07:30:00 
2: 2   C   C 2017-09-25 08:00:00 2017-09-25 10:00:00 
3: 3   A   A 2017-09-25 10:30:00 2017-09-25 13:00:00 
4: 4   C   C 2017-09-25 13:30:00 2017-09-25 15:30:00 
5: 5   B   B 2017-09-25 16:00:00 2017-09-25 18:00:00 
6: 6   B   B 2017-09-25 18:30:00 2017-09-25 19:00:00 
7: 7   A <U+0410> 2017-09-25 19:30:00 2017-09-25 20:00:00 
8: 8   B   C 2017-09-25 20:30:00 2017-09-25 22:00:00 
9: 9   C   B 2017-09-25 22:30:00 2017-09-25 23:00:00 

그런 다음 합치거나 필터링하고 계산하십시오.

idleDT[.("B", "B"), on=.(station_1, station_2), time_2 - time_1 ] 

Time differences in mins 
[1] 360 120 30 

코멘트

내가 분석에 바로 돌아 와이드 포맷으로 이동에도 불구하고 영업 이익의 test 이상 긴 형식 mtest을 선호하는 이유는 아마 설명해야한다 (감사 @Henrik) ...

  • 기지국은 틀림없이 요인이 될 수 있으며 코어 데이터의 두 열을 나누는 경우 두 요소의 수준이 동일해야합니다.
  • 데이터는 아마도 여행의 관점이 아니라 "왼쪽 자전거"및 "자전거 도착"과 같은 이벤트로 기록됩니다. 누군가가 자전거를 훔치거나 길을 잃은 경우, 예를 들어, endtimeend_station은 논리적으로 빠져 있어야하지만, 내 생각에 긴 형식으로 추적하는 것이 더 쉽습니다.
  • 측정 된 데이터는 논리적으로 의미가 없어도 행에 두 개의 "자전거 도착"이벤트가있을 수 있습니다. 경험상 데이터가 잘못 될 수있는 것은 잘못 될 수 있습니다. 이런 일이 발생하면 여행과 관련하여 폭 넓은 형식으로 기록하는 방법을 파악하는 데 어려움을 겪을 수 있습니다.

일반적으로, 난 그냥 데이터 레이아웃에 대한 링크 해들리의 불만에 riffing, tidy data의 내 (아마도 지나치게 또는 잘못) 이해를 적용하고있어 여기서 "[C] olumn 헤더 값이 아닌 변수 이름이다."

+0

당신이 "idleDT"를 만들기 위해'melt' 및'dcast'을 사용하는 좋은 이유가 100 % 확신 (''prev_endstation = shift (end_station)''prev_endtime = shift (endtime))''대신''test '',': =''대신에 현재의 두뇌 상태로는 발견 할 수 없다. 죄송합니다. PLZ 설명을 보내십시오. ;) – Henrik

+1

@Henrik 나는 장황한 설명을 편집했고 몇 가지 설명이 필요하다는 데 동의한다. 그것이 그것이 모두에게 설득력이 있는지 확실하지 않지만 그것이 의미가 있기를 바란다. 감사 :) – Frank

1

dplyr 솔루션 :

library(dplyr) 
df %>% 
    mutate(lag_end_station = lag(end_station), 
     lag_end_time = lag(endtime)) %>% 
    filter(start_station == "B" & lag_end_station == "B") %>% 
    transmute(interval = difftime(starttime, lag_end_time)) 

결과 :

interval 
1 360 mins 
2 120 mins 
3 30 mins 
관련 문제