2017-02-07 14 views
2

私はこのようなデータセットを持っています。行を最大と最小の日付で連結する

id1 = c(1,1,1,1,1,1,1,1,2,2) 
id2 = c(3,3,3,3,3,3,3,3,3,3) 
lat = c(-62.81559,-62.82330, -62.78693,-62.70136, -62.76476,-62.48157,-62.49064,-62.45838,42.06258,42.06310) 
lon = c(-61.15518, -61.14885,-61.17801,-61.00363, -59.14270, -59.22009, -59.32967, -59.04125 ,154.70579, 154.70625) 
start_date= as.POSIXct(c('2016-03-24 15:30:00', '2016-03-24 15:30:00','2016-03-24 23:40:00','2016-03-25 12:50:00','2016-03-29 18:20:00','2016-06-01 02:40:00','2016-06-01 08:00:00','2016-06-01 16:30:00','2016-07-29 20:20:00','2016-07-29 20:20:00'), tz = 'UTC') 
end_date = as.POSIXct(c('2016-03-24 23:40:00', '2016-03-24 18:50:00','2016-03-25 03:00:00','2016-03-25 19:20:00','2016-04-01 03:30:00','2016-06-02 01:40:00','2016-06-01 14:50:00','2016-06-02 01:40:00','2016-07-30 07:00:00','2016-07-30 07:00:00'),tz = 'UTC') 
speed = c(2.9299398, 2.9437502, 0.0220565, 0.0798409, 1.2824859, 1.8685429, 3.7927680, 1.8549291, 0.8140249,0.8287073) 
df = data.frame(id1, id2, lat, lon, start_date, end_date, speed) 

id1 id2  lat  lon   start_date   end_date  speed 
1 1 3 -62.81559 -61.15518 2016-03-24 15:30:00 2016-03-24 23:40:00 2.9299398 
2 1 3 -62.82330 -61.14885 2016-03-24 15:30:00 2016-03-24 18:50:00 2.9437502 
3 1 3 -62.78693 -61.17801 2016-03-24 23:40:00 2016-03-25 03:00:00 0.0220565 
4 1 3 -62.70136 -61.00363 2016-03-25 12:50:00 2016-03-25 19:20:00 0.0798409 
5 1 3 -62.76476 -59.14270 2016-03-29 18:20:00 2016-04-01 03:30:00 1.2824859 
6 1 3 -62.48157 -59.22009 2016-06-01 02:40:00 2016-06-02 01:40:00 1.8685429 
7 1 3 -62.49064 -59.32967 2016-06-01 08:00:00 2016-06-01 14:50:00 3.7927680 
8 1 3 -62.45838 -59.04125 2016-06-01 16:30:00 2016-06-02 01:40:00 1.8549291 
9 2 3 42.06258 154.70579 2016-07-29 20:20:00 2016-07-30 07:00:00 0.8140249 
10 2 3 42.06310 154.70625 2016-07-29 20:20:00 2016-07-30 07:00:00 0.8287073 

実際のデータセットはより大きい。私がしたいのは、このデータセットを日付範囲に基づいて整理し、id1とid2でグループ化しているため、ある行の日付/時間範囲が次の日付/時間範囲のABS(end_date [1] - start_date [2])< 12hrs 'の行は、新しいstart_dateが最も早い日付であり、end_dateが最新のものであることが必要です。他のすべての値(lat、lon、speed)は平均化されます。これは、12時間以内の行が実際に同じ「イベント」を表すため、「重複しない」努力の意味です。上記の例では、最終的な結果は統合最初の4つの行を有する

id1 id2  lat  lon   start_date   end_date  speed 
1 1 3 -62.7818 -61.12142 2016-03-24 15:30:00 2016-03-25 19:20:00 1.493897 
2 1 3 -62.76476 -59.14270 2016-03-29 18:20:00 2016-04-01 03:30:00 1.2824859 
3 1 3 -62.47686 -59.197 2016-06-01 02:40:00 2016-06-02 01:40:00 2.505413 
4 2 3 42.06284 154.706 2016-07-29 20:20:00 2016-07-30 07:00:00 0.8213661 

あろう(ROW1へ)、5行は(ROW2)、統合6-8行(ROW3)放置し、9- 10行統合(row4)。

私はdplyrgroup_bysummarizeでこれをやろうとしていましたが、日付範囲を正しく取得できないようです。

誰かが問題を解決するための簡単な手段を決定してくれることを願ってください。あなたがSQLでそれを行う方法を知っていれば余分な点がありますので、私はこれをRに引き出す前に切り捨てることができます。

+1

[範囲が重複する折りたたみ行(http://stackoverflow.com/questions/41747742/collapse-rows-with-overlapping-ranges)、[崩壊交差領域R](http://stackoverflow.com/questions/16957293/collapse-intersecting-regions-in-r)に行ってください。 – Henrik

答えて

0

ここは初の非常に素朴な実装です。警告:それは遅く、かなりではなく、まだ出力の開始日と終了日がありません!行には日付と時刻の順に並んでいることが必要であることに注意してください。これがデータセットに該当しない場合は、まずRまたはSQLで実行できます。私はdplyrまたはSQLソリューションを考えることができません申し訳ありません。私はまた、誰かがアイデアを持っている場合、それらの2つを見たいと思います。

dedupe <- function(df) { 
    counter = 1 
    temp_vector = unlist(df[1, ]) 
    summarized_df = df[0, c(1, 2, 3, 4, 7)] 
    colnames(summarized_df) = colnames(df)[c(1, 2, 3, 4, 7)] 
    summarized_df$counter = NULL 
    for (i in 2:nrow(df)) { 
    if (((abs(difftime(df[i, "start_date"], df[i - 1, "end_date"], units = "h")) < 
      12) || 
     abs(difftime(df[i, "start_date"], df[i - 1, "start_date"], units = "h")) < 
     12) && 
     df[i, "id1"] == df[i - 1, "id1"] && 
     df[i, "id2"] == df[i - 1, "id2"]) { 
     #group events because id is the same and time range overlap 
     #sum up columns and select maximum end_date 
     temp_vector[c(3, 4, 7)] = temp_vector[c(3, 4, 7)] + unlist(df[i, c(3, 4, 7)]) 
     temp_vector["end_date"] = max(temp_vector["end_date"], df[i, "end_date"]) 
     counter = counter + 1 
     if (i == nrow(df)) { 
     #in the last iteration we need to create a new group 
     summarized_df[nrow(summarized_df) + 1, c(1, 2)] = df[i, c(1, 2)] 
     summarized_df[nrow(summarized_df), 3:5] = temp_vector[c(3, 4, 7)]/counter 
     summarized_df[nrow(summarized_df), "counter"] = counter 
     } 
    } else { 
     #new event so we calculate group statistics for temp_vector and reset its value as well as counter 
     summarized_df[nrow(summarized_df) + 1, c(1, 2)] = df[i, c(1, 2)] 
     summarized_df[nrow(summarized_df), 3:5] = temp_vector[c(3, 4, 7)]/counter 
     summarized_df[nrow(summarized_df), "counter"] = counter 
     counter = 1 
     temp_vector[c(3, 4, 7)] = unlist(df[i, c(3, 4, 7)]) 
    } 
    } 
    return(summarized_df) 
} 

関数呼び出し

> dedupe(df) 
    id1 id2  lat  lon  speed counter 
5 1 3 -62.78179 -61.12142 1.4938968  4 
6 1 3 -62.76476 -59.14270 1.2824859  1 
9 2 3 -62.47686 -59.19700 2.5054133  3 
10 2 3 42.06284 154.70602 0.8213661  2 
関連する問題