我有一个非常大的数据集,它按时间索引。我希望按时间将消息分组在一起,其中第一条消息(在时间T)开始一个组,该组一直持续到时间T + X,此时启动一个新组。数据集可以在观察之间具有大的间隙(> X)
最大组大小(X,以上)是2个时间刻度的示例。专栏" group"是期望的输出:
> example=data.table(time=c(1,2,3,4,8,13,14,17),
group=c(1,1,2,2,3,4,4,5))
> example
time group
1: 1 1
2: 2 1
3: 3 2
4: 4 2
5: 8 3
6: 13 4
7: 14 4
8: 17 5
X = 7时的另一个例子
> example2=data.table(time=c(43,44,75,76,77,80,81,82,83,84), group=c(1,1,2,2,2,2,2,3,3,3))
> example2
time group
1: 43 1
2: 44 1
3: 75 2
4: 76 2
5: 77 2
6: 80 2
7: 81 2
8: 82 3
9: 83 3
10: 84 3
我认为这样做的一种方法是计算时间之间的差异并使用cumsum函数,在达到阈值(在这种情况下为2)后重置为零,但是我还没有弄清楚如何实现这一点重启。我担心我在这里的唯一解决方案最终会被迭代(因此,对于R本身来说太慢了)。
---编辑一些我更具体尝试的例子 首先计算时间增量的cumsum
> example[,cumulativeTime:=cumsum(c(0,diff(time)))]
> example
time group timeDiff cumulativeTime
1: 1 1 NA 0
2: 2 1 1 1
3: 3 2 1 2
4: 4 2 1 3
5: 8 3 4 7
6: 13 4 5 12
7: 14 4 1 13
8: 17 5 3 16
然后考虑将累积时间的模数乘以最大时间滴答数,并考虑当后续模数之间的增量为< 0,这表示一个新的组,但是当你看到数据中存在任何有意义的差距时会发生故障。
> example[,cumTimeMod := cumulativeTime %% 2]
> example
time group timeDiff cumulativeTime cumTimeMod
1: 1 1 NA 0 0
2: 2 1 1 1 1
3: 3 2 1 2 0
4: 4 2 1 3 1
5: 8 3 4 7 1
6: 13 4 5 12 0
7: 14 4 1 13 1
8: 17 5 3 16 0
此外,还尝试了整数除法而不是模数也失败了。不同的例子,其中X = 7(也包含mt1022'以下建议):
time timeDiff cumulativeTime intDivOfCsumByX desiredGroup g1 g2 g
1: 43 0 0 0 1 0 1 1
2: 44 1 1 0 1 0 1 1
3: 75 31 32 4 2 30 1 2
4: 76 1 33 4 2 30 1 2
5: 77 1 34 4 2 30 1 2
6: 80 3 37 5 2 32 1 3
7: 81 1 38 5 2 32 1 3
8: 82 1 39 5 3 32 1 3
9: 83 1 40 5 3 32 1 3
10: 84 1 41 5 3 32 1 3
答案 0 :(得分:1)
我最终采用Rcpp方法来克服R +迭代算法的缓慢性
> x=7
> example2[,assignedGroup:=cumsumgrp(c(0,diff(time)), x-1)]
> example2
time desiredGroup assignedGroup
1: 43 1 0
2: 44 1 0
3: 75 2 1
4: 76 2 1
5: 77 2 1
6: 80 2 1
7: 81 2 1
8: 82 3 2
9: 83 3 2
10: 84 3 2
用法(x-1代表包容性/独占性最大字数。我也不关心组ID的实际数值,只是同一组中的所有消息都具有相同的ID):
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
// Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(CommandViewModel), new PropertyMetadata(null));