R如何找​​到数据中的差距并对差距进行分类

时间:2017-01-03 21:13:51

标签: r dataframe data-analysis

我有以下类型的数据:

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。

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.gapsuser_idexercise_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