如何用tidyverse/dplyr按学生分组追踪课程后续学习路径?
解决方案
用tidyverse/dplyr可以通过分组排序+超前函数轻松实现需求,以下是完整代码和步骤说明:
1. 构造示例数据
先还原输入数据集:
library(tidyverse) # 构造原始数据 df <- tibble( InvoiceDate = ymd(c("2020-07-26", "2020-11-05", "2021-11-05", "2018-10-15", "2020-08-06", "2021-10-10")), StudentName = factor(c("Tom", "Tom", "Tom", "Mary", "Mary", "Mary")), Course = factor(c("Level 1", "Level 2", "Level 3", "Level 1", "Level 2", "Level 2")) )
2. 转换为目标数据集
核心逻辑是按学生分组→按日期排序→用lead()获取下一个课程信息→替换空值为Stop:
result <- df %>% # 按学生分组,确保每个学生的课程单独处理 group_by(StudentName) %>% # 按课程购买日期升序排列,保证时间顺序正确 arrange(InvoiceDate, .by_group = TRUE) %>% # 用lead获取下一个课程和对应的日期,最后一行会返回NA mutate( FollowUpCourse = lead(Course), FollowUpCourseDate = lead(InvoiceDate) ) %>% # 将NA替换为"Stop",先转字符类型避免因子报错 mutate( FollowUpCourse = ifelse(is.na(FollowUpCourse), "Stop", as.character(FollowUpCourse)), FollowUpCourseDate = ifelse(is.na(FollowUpCourseDate), "Stop", as.character(FollowUpCourseDate)) ) %>% # 重命名列名匹配期望输出 rename( FullName = StudentName, StartCourseDate = InvoiceDate, StartCourse = Course ) %>% # 取消分组 ungroup() %>% # 按需转回因子类型(可选) mutate( FullName = factor(FullName), StartCourse = factor(StartCourse), FollowUpCourse = factor(FollowUpCourse) )
3. 输出结果
运行后得到的result即为目标格式:
print(result) # # A tibble: 6 × 5 # FullName StartCourseDate StartCourse FollowUpCourse FollowUpCourseDate # <fct> <date> <fct> <fct> <chr> # 1 Tom 2020-07-26 Level 1 Level 2 2020-11-05 # 2 Tom 2020-11-05 Level 2 Level 3 2021-11-05 # 3 Tom 2021-11-05 Level 3 Stop Stop # 4 Mary 2018-10-15 Level 1 Level 2 2020-08-06 # 5 Mary 2020-08-06 Level 2 Level 2 2021-10-10 # 6 Mary 2021-10-10 Level 2 Stop Stop
关键说明
arrange(InvoiceDate, .by_group = TRUE):必须加.by_group = TRUE,确保排序在每个学生组内进行,而非全局排序。lead()函数:用于获取当前行的下一行数据,最后一行无后续行,返回的NA就是需要标记为Stop的情况。- 因子类型处理:原始Course为因子,直接替换NA会报错,因此先转字符类型替换后,再按需转回因子。
内容的提问来源于stack exchange,提问作者user2133561
相关产品推荐
相关产品推荐

