逐行跟踪完整级别更改

时间:2016-04-27 19:20:26

标签: r data.table dplyr zoo

这就是我的数据框架的样子。最右边的列(“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”专栏。我衷心感谢你的帮助。

2 个答案:

答案 0 :(得分:5)

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

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"

答案 1 :(得分:4)

通过&#39; Name&#39;进行分组后,我们遍历行{({1}})和seq_len(.N)paste&#34;等级&#34;从第一行到相应的行。

unique