逐行跟踪完整级别变化
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
这就是我的数据框的样子。最右边的列("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