2011-12-08 17 views
3

私は2つのデータフレームの融合から作成されたデータフレームを持っています。両者は同じ時間にまたがっていたが、異なる情報を含んでいた。私がそれらをまとめると、データフレームの1つの時間間隔に穴がないので、情報が重なってしまいます。ここでは、行「sp = AおよびB」が最初のdfの一部であり、行「sp = C」が1秒から来る例を示します。最初のデータフレームは連続していますが、2番目のデータフレームは散発的なイベントで構成されています。時間が重複しているときに行を分割するR

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 

私はそれが別の「SP」の時間間隔と重なるときに、「A」又は「B」の時間間隔はそれに応じて切断された「C」を優先したい:得られたデータフレームは、このようになります。この例では、「A」または「B」の1つのイベントに重複する「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 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です。何か不明な点があるのを躊躇しないでください。事前

答えて

2

おかげでここ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 

あなたが欲しいもの。

例のデータセットではすべてがカバーされていないため、いくつかの小さなバグがあるかもしれませんが、これは少なくとも一般的な考えです。それが役に立てば幸い。がんばろう!

+0

うわー、ありがとう!私はいくつかのデータセットで試してみました。それらは十分に獲得されたいくつかの評判のポイントです!よく整理されたきれいな答えに感謝します。 – PEL

+0

@PEL素晴らしい、嬉しい助け! –

関連する問題