2017-09-27 15 views
3

私は、異なるステーションに自転車の軌道を追跡するサンプルデータセットを持っています。私の目標は、時々、自転車は、彼らが終了し、同じ駅で開始し、これらの例はありません先頭行のデータを参照する

> 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.

駅、自転車はこの場合には、 difftime()と特定の駅で残っているの間隔を見つけること です無視する必要があります。上記のデータセットでは、 01:30:0007:30:00の間で360分が経過し、120分が 16:00:0018:00:00の間で経過し、30分が 18:30:0019:00:00の間に経過したことがわかります。自転車が終了した同じ駅で始動しないため、行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"]) 

どのようにしてアカウントに次の行を取るときにのみend_stationdifftime()を計算するであろうと次の行の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 

コメント

私は分析のためにすぐに戻ってワイドフォーマットへ行くにもかかわらず、OPのtestにわたり長期形式mtestを好む、なぜ私はおそらく説明しなければならない(感謝@Henrik)...

  • ステーションはおそらくファクタである必要がありますが、コアデータ内の2つの列に分割されている場合、両方の要素が同じレベルになるようにするのは負担です。
  • データはおそらく、旅行の点ではなく、「自転車の左」と「自転車が到着しました」のようなイベントの面で記録されます。たとえば、誰かが自転車を盗んだり、迷子になったりすると、endtimeend_stationが論理的に欠けているはずですが、これは長いフォーマットで追跡するのが簡単です。
  • 測定されたデータには論理的に意味をなさないものの、2つの「バイク到着」イベントがあっても、データで間違っているものは間違っています。これが起こった場合、あなたは旅行の観点からそれをワイドフォーマットで記録する方法を考え出すのが難しいでしょう。

一般的に、私は単なるデータのレイアウトに関するリンクにハドレーの苦情にリフ、tidy dataの私の(おそらく熱心または間違った)理解を適用していますここで、「[C] olumnヘッダの値ではなく、変数名です。」

+0

私はあなたが "idleDT" を作成するために 'melt'&' dcast'を使用するための十分な理由を持っている100%確信しています残念ながら私の現在の脳の状態は私にそれを見つけさせません。ごめんなさい。 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 
関連する問題