将定时序列分解为剧集

时间:2016-02-03 02:14:37

标签: r

我试图将事件时间向量分解为剧集。一集必须符合2个标准。 1)它由3个或更多事件组成; 2)这些事件的事件间时间为25个单位或更少。我的数据在数据框中组织,如下所示。

到目前为止,我发现我可以通过diff(EventTime)找到事件之间的区别。通过创建一个与第二个事件间标准事件相对应的逻辑向量,我可以使用rle(EpisodeTimeCriterion)来获得总数和剧集的长度。

    EventTime   TimeDifferenceBetweenNextEvent     EpisodeTimeCriterion
    25          NA                                 NA
    75          50                                 TRUE
    100         25                                 TRUE
    101         1                                  TRUE
    105         4                                  TRUE
    157         52                                 FALSE
    158         1                                  TRUE
    160         2                                  TRUE
    167         7                                  TRUE
    169         2                                  TRUE
    170         1                                  TRUE
    175         5                                  TRUE
    178         3                                  TRUE
    278         100                                FALSE
    302         24                                 TRUE
    308         6                                  TRUE
    320         12                                 TRUE
    322         459                                FALSE

但是,我想知道剧集的发布时间和' rle()'不让我这样做。

理想情况下,我想生成一个如下所示的数据框:

    Episode      EventsPerEpisode   EpisodeStartTime   EpisodeEndTime
    1            4                  75                 105
    2            7                  158                178
    3            3                  302                322

我知道这可能是一个简单的问题,但对R来说是新手,我能想到的唯一解决方案是一系列循环。有没有循环的方法吗?或者是否有适合这种分析的软件包?

谢谢!

编辑清晰。添加了所需的结果数据名称并扩展了示例数据以使其更清晰。

2 个答案:

答案 0 :(得分:0)

Here is one approach I came up with using a combination of cut2 from Hmisc package and cumsum to label episodes into numbers:

library(Hmisc)
library(dplyr)
df$episodeCut <- cut2(df$TimeDifferenceBetweenNextEvent, c(26))
df$episode <- cumsum((df$episodeCut == '[ 1,26)' & lag(df$episodeCut) != '[ 1,26)') | df$episodeCut != '[ 1,26)')

Output is as follows:

  EventTime TimeDifferenceBetweenNextEvent EpisodeTimeCriterion episodeCut episode
1        25                             50                FALSE    [26,52]       1
2        75                             25                 TRUE    [ 1,26)       2
3       100                              1                 TRUE    [ 1,26)       2
4       101                              4                 TRUE    [ 1,26)       2
5       105                             52                 TRUE    [26,52]       3
6       157                             52                FALSE    [26,52]       4

As you can see, it tags rows 2, 3, 4 as belonging to a single episode.

Is this what you are looking for? Not sure from your description. So, my answer may be wrong.

答案 1 :(得分:0)

你已经得到了你需要的东西。你真的需要创建一个变量,为每个剧集提供一个数字/名称,以便你可以按照它进行分组。 rle(...)$length为您提供了运行长度,因此只需使用rep重复一次该数字:

runs <- rle(df$EpisodeTimeCriterion)$lengths   # You don't need this extra variable, but it makes the code more readable
df$Episode <- rep(1:length(runs), runs)

所以df看起来像

> head(df)
  EventTime TimeDifferenceBetweenNextEvent EpisodeTimeCriterion Episode
1        25                             NA                   NA       1
2        75                             50                 TRUE       2
3       100                             25                 TRUE       2
4       101                              1                 TRUE       2
5       105                              4                 TRUE       2
6       157                             52                FALSE       3

现在使用dplyr汇总数据:

library(dplyr)
df2 <- df %>% filter(EpisodeTimeCriterion) %>% group_by(Episode) %>% 
  summarise(EventsPerEpisode = n(), 
            EpisodeStartTime = min(EventTime), 
            EpisodeEndTime = max(EventTime))

返回

> df2
Source: local data frame [3 x 4]

  Episode EventsPerEpisode EpisodeStartTime EpisodeEndTime
    (int)            (int)            (dbl)          (dbl)
1       2                4               75            105
2       4                7              158            178
3       6                3              302            320

如果您希望您的剧集编号为以1开头的整数,则可以使用

进行清理
df2$Episode <- 1:nrow(df2)

数据

如果有人想在运行上述代码之前使用数据,dput(df)的结果:

df <- structure(list(EventTime = c(25, 75, 100, 101, 105, 157, 158, 
    160, 167, 169, 170, 175, 178, 278, 302, 308, 320, 322), TimeDifferenceBetweenNextEvent = c(NA, 
    50, 25, 1, 4, 52, 1, 2, 7, 2, 1, 5, 3, 100, 24, 6, 12, 459), 
    EpisodeTimeCriterion = c(NA, TRUE, TRUE, TRUE, TRUE, FALSE, 
    TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, 
    TRUE, FALSE)), .Names = c("EventTime", "TimeDifferenceBetweenNextEvent", 
    "EpisodeTimeCriterion"), row.names = c(NA, -18L), class = "data.frame")