【问题标题】:How to create variables that indicate start and end periods in a time series in R如何在R中创建指示时间序列中开始和结束时段的变量
【发布时间】:2014-09-21 00:49:17
【问题描述】:

我想计算某人何时开始和停止评论博客。我的数据集在第 1 列中有一个用户 ID,后跟 6 列,每列代表一个时间段内的 cmets 数。我想创建一个列(“活动”)来标识出现非零值的第一个时期。我还想创建一个列(“非活动”),用于标识第一个周期,其中零跟随一个非零值,并且在后续周期中仅跟随零。

这是10行样本数据:

structure(list(userid = c(199782L, 30982L, 27889L, 108358L, 29620L, 
229214L, 37531L, 711L, 30516L, 32360L), Period1 = c(0L, 1L, 43L, 
0L, 189L, 0L, 0L, 142L, 26L, 0L), Period2 = c(0L, 36L, 40L, 18L, 
32L, 0L, 6L, 55L, 159L, 0L), Period3 = c(0L, 68L, 25L, 110L, 
1L, 0L, 31L, 14L, 32L, 0L), Period4 = c(0L, 45L, 0L, 91L, 0L, 
0L, 54L, 1L, 0L, 0L), Period5 = c(93L, 27L, 57L, 0L, 0L, 35L, 
79L, 4L, 0L, 26L), Period6 = c(132L, 47L, 37L, 4L, 0L, 186L, 
50L, 2L, 0L, 191L)), .Names = c("userid", "Period1", "Period2", 
"Period3", "Period4", "Period5", "Period6"), row.names = 175:184, class = "data.frame")

以下是 5 行的选定输出。 'inactive' 没有值意味着用户仍然处于活动状态。:

userid, active, inactive
199782, 5
27889, 1
29620, 1, 3
37531, 2
30516, 1, 3

有人可以为我指出如何解决这个问题的正确方向吗?谢谢!

【问题讨论】:

  • 您的active 列可能是apply(df[-1] > 0, 1, match, x = TRUE) 另一列需要更多考虑。你关心空的inactives 是不是NA?我想我会更好。
  • 谢谢理查德。是的,不活动的可以是 NA

标签: r


【解决方案1】:

使用 data.table 进行糖语法并按组 id 进行(放入长格式后):

library(data.table)
melt(setDT(dat),id.vars='userid')[,
    list(active=min(which(value>0)),
         inactive={ mm = cumsum(value)
                    ## treat the case where we have leading 0 in value
                    mm = duplicated(mm[mm!=0])
               ## Note the use of integer here otheriwse data.table will complain about types...
                       ifelse(any(mm) && max(which(mm))==length(value),
                               min(which(mm)),NA_integer_)
         }),userid]

     userid active inactive
 1: 199782      5       NA
 2:  30982      1       NA
 3:  27889      1       NA
 4: 108358      2       NA
 5:  29620      1        4
 6: 229214      5       NA
 7:  37531      2       NA
 8:    711      1       NA
 9:  30516      1        4
10:  32360      5       NA

解释,对于每个id:

  1. 活动列只是第一个值的索引,不为空
  2. 非活动列比较棘手。它是重复值在值的累积和中的最小索引。我们应该从这个累积和中删除空值,以避免值以零开头的情况。这里举个简单的例子:

     cumsum(c(1,0,1))  
    [1] 1 1 2
          _    ## we want to extract the index of one here
    min(which(duplicated(cumsum(c(1,0,1)))))
    2 
    

【讨论】:

  • 谢谢。这可以正确识别“活动”,但“非活动”不能正常工作。它似乎是在非零之后标记第一个零,但有时这只是一个暂停,并且在随后的时期内有活动。例如,用户 ID 27889 在第 1-3 期有活动,在第 4 期没有活动,然后在第 5-6 期恢复。
  • @user3614783 好。你的意思是一旦用户变得不活跃,他就不能再次活跃?
  • @user3614783 我稍微修改了条件,将非活动期定义为第一个非零期,随后的期只跟零。
  • 对不起,我应该更清楚。我对不活动的定义是在此之后不再有活动的时期。如果 P1-P6 活动为 1,0,1,1,0,0,则“不活动”2,因为活动在 P3 中恢复。 "inactive'=5 因为在 5 之后只有零。
  • @user3614783 在您的示例中,预期输出为:30516, 1, 4 而不是30516, 1, 3。不管怎样,我认为我的最后一次编辑给了你正确的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
  • 2019-12-06
  • 1970-01-01
  • 2021-06-20
相关资源
最近更新 更多