6

私は R が大好きですが、いくつかの問題は単純に難しいものです。

課題は、時間ベースのウィンドウが 6 時間以上の不規則な時系列で、ローリング サムが 30 未満になる最初のインスタンスを見つけることです。シリーズのサンプルを持っています

Row Person  DateTime    Value
1   A   2014-01-01 08:15:00 5
2   A   2014-01-01 09:15:00 5
3   A   2014-01-01 10:00:00 5
4   A   2014-01-01 11:15:00 5
5   A   2014-01-01 14:15:00 5
6   B   2014-01-01 08:15:00 25
7   B   2014-01-01 10:15:00 25
8   B   2014-01-01 19:15:00 2
9   C   2014-01-01 08:00:00 20
10  C   2014-01-01 09:00:00 5
11  C   2014-01-01 13:45:00 1
12  D   2014-01-01 07:00:00 1
13  D   2014-01-01 08:15:00 13
14  D   2014-01-01 14:15:00 15

For Person A, Rows 1 & 5 create a minimum 6 hour interval with a running sum of 25 (which is less than 30).
For Person B, Rows 7 & 8 create a 9 hour interval with a running sum of 27 (again less than 30).
For Person C, using Rows 9 & 10, there is no minimum 6 hour interval (it is only 5.75 hours) although the running sum is 26 and is less than 30.
For Person D, using Rows 12 & 14, the interval is 7.25 hours but the running sum is 30 and is not less than 30.

n 個の観測が与えられた場合、比較する必要がある n*(n-1)/2 の間隔があります。たとえば、n=2 の場合、評価する間隔は 1 つだけです。n=3 の場合、3 つの間隔があります。等々。

これは部分和問題のバリエーションだと思います ( http://en.wikipedia.org/wiki/Subset_sum_problem )

データを並べ替えることができますが、これには各間隔をテストするブルート フォース ソリューションが必要であると思われます。

どんな助けでも大歓迎です。


編集: DateTime 列が POSIXct としてフォーマットされたデータは次のとおりです。

df <- structure(list(Person = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 3L, 3L, 3L, 4L, 4L, 4L), .Label = c("A", "B", "C", "D"), class = "factor"), 
DateTime = structure(c(1388560500, 1388564100, 1388566800, 
1388571300, 1388582100, 1388560500, 1388567700, 1388600100, 
1388559600, 1388563200, 1388580300, 1388556000, 1388560500, 
1388582100), class = c("POSIXct", "POSIXt"), tzone = ""), 
Value = c(5L, 5L, 5L, 5L, 5L, 25L, 25L, 2L, 20L, 5L, 1L, 
1L, 13L, 15L)), .Names = c("Person", "DateTime", "Value"), row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14"), class = "data.frame")
4

3 に答える 3

1

間隔は、同じ人物の 2 つの行によって定義されると仮定します。各人についてValue、これらの 2 行と中間行の合計が 30 未満である、少なくとも 6 時間の最初のそのような間隔 (時間単位) が必要です。人にそのような最初の間隔が複数ある場合任意に 1 つを選択します。

これは、SQL のトリプル結合で表すことができます。a.DateTime内部選択は、間隔の開始 ( )、間隔の終了 ( ) 、およびb.DateTimeそれらの間の行( )で構成されるすべての行を選択します。外側の選択では、30 未満の行のみが保持され、それぞれが最小の行のみが保持されます。a の最初の行が (時間的に) 複数ある場合は、任意に 1 つが選択されます。c.DateTimePersonValuehourstotalPersonDateTimePerson

   library(sqldf)

   sqldf(
     "select Person, min(Datetime) DateTime, hours, total 
      from (select a.Person, 
          a.DateTime, 
          (b.Datetime - a.DateTime)/3600 hours, 
          sum(c.Value) total
          from DF a join DF b join DF c
          on a.Person = b.Person and a.Person = c.Person and hours >= 6
          and c.DateTime between a.DateTime and b.DateTime
          group by a.Person, a.DateTime, b.DateTime)
      where total < 30
      group by Person"
   )

与える:

  Person            DateTime hours total
1      A 2014-01-01 08:15:00  6.00    25
2      B 2014-01-01 10:15:00  9.00    27
3      D 2014-01-01 07:00:00  7.25    29

注:次のデータを使用しました。

DF <- data.frame( Row = 1:14,
  Person = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
             4L, 4L), .Label = c("A", "B", "C", "D"), class = "factor"),
  DateTime = structure(c(1388582100, 1388585700, 1388588400, 1388592900, 
             1388603700, 1388582100, 1388589300, 1388621700, 1388581200, 
             1388584800, 1388601900, 1388577600, 1388582100, 1388603700), 
             class = c("POSIXct", "POSIXt"), tzone = ""),
  Value = c(5L, 5L, 5L, 5L, 5L, 25L, 25L, 2L, 20L, 5L, 1L, 1L, 13L, 15L) ) 
于 2014-08-05T14:37:09.460 に答える