我有以下类型的数据:
all_exercises <- c(1,2,9,4,5,7,6,8,3)
user_id <- c(14,14,14,14,14,16,16,16,16,16)
exercise_id <- c(1,2,9,4,5,1,2,4,5,6)
df <- data.frame(user_id,exercise_id)
df
user_id exercise_id
1 14 1
2 14 2
3 14 9
4 14 4
5 14 5
6 16 1
7 16 2
8 16 4
9 16 5
10 16 6
现在我有兴趣找到连续三次没有参加所有练习的用户。练习的顺序与1:9有些不同,如果用户之间有差距,他也应该考虑。在我的例子中,用户14退出了因为他没有参加练习7,6,8,3。用户16不会退出,因为练习的间隙最大为2。
答案 0 :(得分:1)
这是dplyr
的解决方案,但这可能是重复的......
library(dplyr)
df.gaps <- df %>%
arrange(user_id, exercise_id) %>%
group_by(user_id) %>%
mutate(gap = exercise_id - lag(exercise_id, default = 0))
df.gaps %>%
filter(gap > 3)
df.gaps
按user_id
和exercise_id
对数据进行排序(假设练习按顺序排列)。然后我们group_by
user_id
以创建窗口函数差异(请参阅this window functions vignette) - 我还将默认值设置为零,以便不会产生NA
。< / p>
最后,您可以过滤此新的df.gaps
data.frame以获得结果。
基础R
解决方案可能如下所示:
df <- df[order(df$user_id, df$exercise_id), ]
temp <- by(df$exercise_id, df$user_id, function(x) diff(x) > 3)
sapply(temp, any)
答案 1 :(得分:0)
溶液
df.gaps <- df %>%
mutate(exercise_id = factor(exercise_id, all_exercises)) %>%
arrange(user_id, exercise_id) %>%
mutate(exercise_id_num = as.numeric(exercise_id)) %>%
group_by(user_id) %>%
mutate(gap = lead(exercise_id_num) - exercise_id_num - 1)
mutate(gap = ifelse(is.na(gap), nlevels(all_exercises)-exercise_id_num, no=gap))
df.gaps
user_id exercise_id exercise_id_num gap
<dbl> <fctr> <dbl> <dbl>
1 14 1 1 0
2 14 2 2 0
3 14 9 3 0
4 14 4 4 0
5 14 5 5 4
6 16 1 1 0
7 16 2 2 1
8 16 4 4 0
9 16 5 5 1
10 16 6 7 2