逐行跟踪完整级别变化

Tracking full Level change row by row

这就是我的数据框的样子。最右边的列("FullCycle")是我想要的列。对于给定的名称和给定的时间点,我想查看一个人的整个级别变化周期。

 library(data.table)
     dt <- fread('
        Name      Level     Date         RecentLevelChange  FullCycle
        John       1       2016-01-01       NA                1
        John       1       2016-01-10       NA                1
        John       2       2016-01-17       1->2              1->2
        John       2       2016-01-18       NA                1->2
        John       3       2016-01-19       2->3              1->2->3
        John       4       2016-01-20       3->4              1->2->3->4
        John       4       2016-01-21       NA                1->2->3->4
        John       7       2016-01-22       4->7              1->2->3->4->7
        Tom        1       2016-01-10       NA                1
        Tom        2       2016-01-17       1->2              1->2
        Tom        2       2016-01-18       NA                1->2
        Tom        3       2016-01-19       2->3              1->2->3
        Tom        4       2016-01-20       3->4              1->2->3->4
        Tom        4       2016-01-21       NA                1->2->3->4
        Tom        7       2016-01-22       4->7              1->2->3->4->7
  ')

我通过尝试

创建了字段 "RecentLevelChange"
require(dplyr)
dt[,RecentLevelChange := 
as.character(ifelse(lag(Level)==Level  ,NA,
paste(lag(Level),Level,sep="->"))),by=Name]

但我不知道如何创建“FullCycle”栏。非常感谢您的帮助。

这里有一个计算路径的辅助函数

paths <- function(x) {
    sapply(Reduce(function(prev, cur) 
        unique(c(prev,cur)), x, accumulate=T), 
        function(x) paste(x, collapse="->")
    )
 }

使用 Reduce() 构建达到给定点的唯一级别列表。 (这假定行已正确排序)。然后我们可以将这个函数应用到每个人

dt[,path:=paths(Level), by="Name"]

这会产生

    Name Level       Date RecentLevelChange          path
 1: John     1 2016-01-01                NA             1
 2: John     1 2016-01-10                NA             1
 3: John     2 2016-01-17              1->2          1->2
 4: John     2 2016-01-18                NA          1->2
 5: John     3 2016-01-19              2->3       1->2->3
 6: John     4 2016-01-20              3->4    1->2->3->4
 7: John     4 2016-01-21                NA    1->2->3->4
 8: John     7 2016-01-22              4->7 1->2->3->4->7
 9:  Tom     1 2016-01-10                NA             1
10:  Tom     2 2016-01-17              1->2          1->2
11:  Tom     2 2016-01-18                NA          1->2
12:  Tom     3 2016-01-19              2->3       1->2->3
13:  Tom     4 2016-01-20              3->4    1->2->3->4
14:  Tom     4 2016-01-21                NA    1->2->3->4
15:  Tom     7 2016-01-22              4->7 1->2->3->4->7

如果您想跟踪用户是否回到了他们之前的水平,您可以改用类似这样的东西

paths <- function(x) {
    sapply(Reduce(function(prev, cur) 
        rle(c(prev,cur))$values, x, accumulate=T), 
        function(x) paste(x, collapse="->")
    )
 }

例如

paths(c(1,2,3,2,1))
# [1] "1"             "1->2"          "1->2->3"       "1->2->3->2"   
# [5] "1->2->3->2->1"

按'Name'分组后,我们遍历行序列(seq_len(.N))和paste unique "Level" 从第一行到相应的行行。

dt[,FullCycle := vapply(seq_len(.N), function(i) 
       paste(unique(Level[1:i]), collapse="->"), character(1)) , by = Name]
dt
#    Name Level       Date RecentLevelChange     FullCycle
# 1: John     1 2016-01-01                NA             1
# 2: John     1 2016-01-10                NA             1
# 3: John     2 2016-01-17              1->2          1->2
# 4: John     2 2016-01-18                NA          1->2
# 5: John     3 2016-01-19              2->3       1->2->3
# 6: John     4 2016-01-20              3->4    1->2->3->4
# 7: John     4 2016-01-21                NA    1->2->3->4
# 8: John     7 2016-01-22              4->7 1->2->3->4->7
# 9:  Tom     1 2016-01-10                NA             1
#10:  Tom     2 2016-01-17              1->2          1->2
#11:  Tom     2 2016-01-18                NA          1->2
#12:  Tom     3 2016-01-19              2->3       1->2->3
#13:  Tom     4 2016-01-20              3->4    1->2->3->4
#14:  Tom     4 2016-01-21                NA    1->2->3->4
#15:  Tom     7 2016-01-22              4->7 1->2->3->4->7