R - 使用时间来限制组的大小

时间:2017-04-26 02:35:53

标签: r data.table dplyr rcpp cumsum

我有一个非常大的数据集,它按时间索引。我希望按时间将消息分组在一起,其中第一条消息(在时间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

1 个答案:

答案 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));