我有一些样本数据,其中存在(错误的)重叠间隔,因此我想将数据拆分为非重叠间隔,根据原始数据向每个间隔添加数据。
假设我有一个这样的数据表:
x <- c(1000, 2000, 2000, 1000, 1500)
y <- c(1200, 3000, 4000, 2000, 3000)
z <- c("a", "a", "a", "b", "b")
n1 <- 1:5
n2 <- 4:8
DT <- data.table(id=z,
start=as.POSIXct(x, origin = "2016-01-01"),
end=as.POSIXct(y, origin = "2016-01-01"),
x=x,
y=y,
data1=n1,
data2=n2)
DT
id start end x y data1 data2
1: a 2016-01-01 01:16:40 2016-01-01 01:20:00 1000 1200 1 4
2: a 2016-01-01 01:33:20 2016-01-01 01:50:00 2000 3000 2 5
3: a 2016-01-01 01:33:20 2016-01-01 02:06:40 2000 4000 3 6
4: b 2016-01-01 01:16:40 2016-01-01 01:33:20 1000 2000 4 7
5: b 2016-01-01 01:25:00 2016-01-01 01:50:00 1500 3000 5 8
对于每个id,我想使用每个间隔内的数据总和来聚合数据。对于id==a
,它看起来像这样:
1: a 2016-01-01 01:16:40 2016-01-01 01:20:00 1000 1200 1 4
2: a 2016-01-01 01:33:20 2016-01-01 01:50:00 2000 3000 3.5 8
3: a 2016-01-01 01:50:01 2016-01-01 02:06:40 3001 4000 1.5 3
由于第3行的一半会被添加到第2行。对于id=="b"
,它会变得更复杂一些:
4: b 2016-01-01 01:16:40 2016-01-01 01:24:59 1000 1499 2 3.5
5: b 2016-01-01 01:25:00 2016-01-01 01:33:20 1500 2000 3.67 6.16
6: b 2016-01-01 01:33:21 2016-01-01 01:50:00 2001 3000 3.33 5.33
这里增加了一行,因为我们有三个不同的时间。根据原始区间中的数据将数据分成每一行。例如,DT$data1[5]
计算为1/2 * 4 + 1/3 * 5
。
我假设你可以在data.table中使用foverlaps,但我真的不知道如何。请帮忙。
答案 0 :(得分:1)
我不清楚逻辑如何使用权重或如何减去或添加开始和停止时间。但是,您可能会发现data.table
对于获取所需的最终表格非常有用:
> (unique_times <- DT[
+ , .(times = sort(unique(c(x, y)))), by = id][
+ , `:=`(new_start = times, new_end = shift(times, type = "lead")),
+ by = id][
+ !is.na(new_end)][
+ , times := NULL])
> unique_times
id new_start new_end
1: a 1000 1200
2: a 1200 2000
3: a 2000 3000
4: a 3000 4000
5: b 1000 1500
6: b 1500 2000
7: b 2000 3000
>
> # add data1 and data2 and x and y. The later to compute weights later
> unique_times <- unique_times[
+ DT, .(id, x, y, data1, data2, x.new_start, new_end),
+ on = .(id, new_start <= y), allow.cartesian = TRUE][
+ x < new_end & y > x.new_start]
> unique_times
id x y data1 data2 x.new_start new_end
1: a 1000 1200 1 4 1000 1200
2: a 2000 3000 2 5 2000 3000
3: a 2000 4000 3 6 2000 3000
4: a 2000 4000 3 6 3000 4000
5: b 1000 2000 4 7 1000 1500
6: b 1000 2000 4 7 1500 2000
7: b 1500 3000 5 8 1500 2000
8: b 1500 3000 5 8 2000 3000
我认为可以使用by
,id
和x.new_start
使用new_end
参数进行最后一步。