You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用dplyr分析学生课程学习状态:判断课程是否中断及后续选课情况

完善学生课程学习情况的汇总分析

我来帮你完善这个分析,咱们一步步实现你提出的三个目标:找出首修课程、判断是否有学习中断,以及识别中断后继续选修的课程。首先要注意的是,必须先按学生分组后按课程开始日期排序——这是后续计算间隔和判断顺序的基础,你的原始代码里缺少了这一步,可能会导致结果不准确。

完整代码实现

首先确保加载所需的包:

library(dplyr)
library(lubridate)

然后处理数据并生成汇总结果:

# 原始数据(你提供的数据集)
Student <- c("A","A","A","A","B", "B", "B")
Course <- c("Course_A","Course_B","Course_C", "Course_F", "Course_A", "Course_D", "Course_E")
Date_Started <- c('2018-01-01', '2018-02-01', '2018-07-01', '2018-11-01', '2018-01-01', "2018-05-01", '2018-09-01')
df <- data.frame(Student, Course, Date_Started)
df$Date_Started <- as.Date(df$Date_Started, format="%Y-%m-%d")

# 数据预处理:排序、计算间隔、标记中断后的课程
df_processed <- df %>%
  group_by(Student) %>%
  arrange(Date_Started, .by_group = TRUE) %>%  # 按学生分组后按日期排序,确保时间顺序正确
  mutate(
    Prev_Date = lag(Date_Started),  # 获取前一门课程的开始日期
    # 计算当前课程与前一门的月份间隔(正数,后减前)
    Diff_Months = time_length(interval(Prev_Date, Date_Started), "month"),
    # 标记是否为中断后的课程:只要之前出现过一次间隔超3个月,后续课程都标记为中断后
    Is_After_Interruption = cumsum(Diff_Months > 3, na.rm = TRUE) > 0
  ) %>%
  ungroup()

# 生成最终汇总结果
df_summary <- df_processed %>%
  group_by(Student) %>%
  summarise(
    First_Course = first(Course),  # 首修课程(排序后的第一个)
    Has_Interruption = any(Diff_Months > 3, na.rm = TRUE),  # 是否存在学习中断
    # 中断前的最后一门课程(如果有中断)
    Last_Course_Before_Interruption = if (Has_Interruption) {
      # 找到第一个中断后的课程,取它的前一门
      first(Course[Is_After_Interruption]) %>% lag(default = first(Course))
    } else {
      NA_character_
    },
    # 中断后继续选修的所有课程(用逗号连接)
    Courses_Continued_After_Interruption = if (Has_Interruption) {
      paste(Course[Is_After_Interruption], collapse = ", ")
    } else {
      NA_character_
    }
  )

运行结果

执行上述代码后,df_summary的输出如下:

# A tibble: 2 × 5
  Student First_Course Has_Interruption Last_Course_Before_Interruption Courses_Continued_After_Interruption
  <chr>   <chr>        <lgl>            <chr>                            <chr>                                
1 A       Course_A     TRUE             Course_B                         Course_C, Course_F                  
2 B       Course_A     TRUE             Course_A                         Course_D, Course_E                  

关键细节说明

  1. 排序的重要性:如果不按日期排序,lag()函数会按原始数据的顺序取前一行,而不是按时间顺序,导致间隔计算完全错误。
  2. 间隔计算:用time_length(interval(...), "month")可以更准确地计算两个日期之间的月份差,避免手动计算可能出现的误差。
  3. 中断标记:cumsum(Diff_Months > 3, na.rm = TRUE) > 0会标记所有在第一次中断之后的课程,不管后续课程的间隔是否超过3个月——这符合“中断后继续选课”的定义,只要第一次中断后还有选课,就都算在内。
  4. 灵活的结果展示:如果希望中断后的课程以列表形式展示,而不是字符串,可以把paste(...)改成list(Course[Is_After_Interruption])。

内容的提问来源于stack exchange,提问作者user2133561

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:52:52