Разделение строк, когда время пересекается в R - PullRequest
3 голосов
/ 08 декабря 2011

У меня есть фрейм данных, который был создан из слияния двух фреймов данных. Оба охватывали одно и то же время, но содержали разную информацию. Когда я собрал их вместе, информация перекрылась, так как во временном интервале одного из фреймов данных нет дыр. Вот пример, где строки "sp = A и B" являются частью первого df, а строки "sp = C" происходят от второго. Первый кадр данных является непрерывным, а второй состоит из спорадических событий. Результирующий кадр данных выглядит следующим образом:

start                  end                         sp
2010-06-01 17:00:00    2010-06-01 19:30:00         A
2010-06-01 19:30:01    2010-06-01 20:00:00         B
2010-06-01 19:45:00    2010-06-01 19:55:00         C
2010-06-01 20:00:01    2010-06-01 20:30:00         A
2010-06-01 20:05:00    2010-06-01 20:10:00         C
2010-06-01 20:12:00    2010-06-01 20:15:00         C
2010-06-01 20:30:01    2010-06-01 20:40:00         B
2010-06-01 20:35:00    2010-06-01 20:40:10         C
2010-06-01 20:40:01    2010-06-01 20:50:00         A

Я бы хотел расставить приоритеты "C", чтобы, когда он перекрывал временной интервал другого "sp", временной интервал "A" или "B" соответственно сокращался. Как видно из примера, у меня иногда есть несколько событий «C», которые перекрывают одно событие «A» или «B». Результат будет следующим:

start                  end                         sp
2010-06-01 17:00:00    2010-06-01 19:30:00         A
2010-06-01 19:30:01    2010-06-01 19:44:59         B
2010-06-01 19:45:00    2010-06-01 19:55:00         C
2010-06-01 19:55:01    2010-06-01 20:00:00         B
2010-06-01 20:00:01    2010-06-01 20:04:59         A
2010-06-01 20:05:00    2010-06-01 20:10:00         C
2010-06-01 20:10:01    2010-06-01 20:11:59         A
2010-06-01 20:12:00    2010-06-01 20:15:00         C
2010-06-01 20:15:01    2010-06-01 20:30:00         A
2010-06-01 20:30:01    2010-06-01 20:34:59         B
2010-06-01 20:35:00    2010-06-01 20:40:10         C
2010-06-01 20:40:11    2010-06-01 20:50:00         A 

Мои столбцы даты / времени находятся в POSIXct. Не стесняйтесь спрашивать, если что-то неясно.

Заранее спасибо

1 Ответ

2 голосов
/ 10 декабря 2011

Вот хороший способ сделать это с пакетом plyr и рекурсивной функцией:

library(plyr)

splitTimes <- function(arow, df) {
  overlap_all    = arow$start > df[, 'start'] & arow$end < df[, 'end']
  overlap_middle = arow$start < df[, 'start'] & arow$end > df[, 'end']
  overlap_end    = arow$start < df[, 'start'] & arow$end > df[, 'start'] & arow$end < df[, 'end']
  overlap_start  = arow$start > df[, 'start'] & arow$end > df[, 'end'] & arow$start < df[, 'end']

  if(any(overlap_all)) {
    data.frame()
  } else if(any(overlap_middle)) {
    outrows = rbind(data.frame(start=arow$start, end=df[overlap_middle, 'start'][1]-1, sp=arow$sp),
                    data.frame(start=df[overlap_middle, 'end'][1]+1, end=arow$end, sp=arow$sp))
    ddply(outrows, 'start', 'splitTimes', df)
  } else if(any(overlap_end)) {
    data.frame(start=arow$start, end=df[overlap_end, 'start']-1, sp=arow$sp)
  } else if(any(overlap_start)) {
    data.frame(start=df[overlap_start, 'end']+1, end=arow$end, sp=arow$sp)
  } else {
    arow
  }
}

Тогда вы можете сделать:

> dfall = read.table('data.txt', header=T, colClasses=c('POSIXct', 'POSIXct', 'factor'))

> dfAB = subset(dfall, sp %in% c('A', 'B'))
> dfC  = subset(dfall, sp == 'C')

> arrange(rbind(ddply(dfAB, 'start', 'splitTimes', dfC), dfC), start)
                 start                 end sp
1  2010-06-01 17:00:00 2010-06-01 19:30:00  A
2  2010-06-01 19:30:01 2010-06-01 19:44:59  B
3  2010-06-01 19:45:00 2010-06-01 19:55:00  C
4  2010-06-01 19:55:01 2010-06-01 20:00:00  B
5  2010-06-01 20:00:01 2010-06-01 20:04:59  A
6  2010-06-01 20:05:00 2010-06-01 20:10:00  C
7  2010-06-01 20:10:01 2010-06-01 20:11:59  A
8  2010-06-01 20:12:00 2010-06-01 20:15:00  C
9  2010-06-01 20:15:01 2010-06-01 20:30:00  A
10 2010-06-01 20:30:01 2010-06-01 20:34:59  B
11 2010-06-01 20:35:00 2010-06-01 20:40:10  C
12 2010-06-01 20:40:11 2010-06-01 20:50:00  A

, которая дает вам именно то, что выwant.

В других случаях могут быть небольшие ошибки, поскольку ваш пример данных не охватывает их все, но это, по крайней мере, общая идея.Надеюсь, поможет.Удачи!

...