如何用R语言识别成绩持续提升或下降的学生?
问题分析与修正
错误原因
你写的自定义函数逻辑本身没问题,但在filter()里调用时犯了关键错误:filter()是逐行处理数据的,你的函数实际接收的是每行的单个成绩值,而不是整个学生的成绩向量。这导致循环根本不会执行(因为单个值的长度是1,i从2开始的循环直接跳过),函数直接返回TRUE,但后续分组过滤的逻辑完全混乱,最终得到空结果。
修正后的代码
不需要自定义循环函数,用dplyr的窗口函数lag()就能轻松实现需求,而且更符合分组操作的逻辑:
筛选成绩逐年提升(或持平)的学生
library(dplyr) improving_students <- my_data %>% group_by(id) %>% # 显式按年份排序,确保是逐年的顺序(你的数据已经有序,但显式处理更稳妥) arrange(year, .by_group = TRUE) %>% # 检查组内所有相邻成绩:当前成绩 >= 前一年成绩 filter(all(grade >= lag(grade, default = first(grade)))) %>% select(id) %>% unique()
筛选成绩逐年下降(或持平)的学生
worse_students <- my_data %>% group_by(id) %>% arrange(year, .by_group = TRUE) %>% # 检查组内所有相邻成绩:当前成绩 <= 前一年成绩 filter(all(grade <= lag(grade, default = first(grade)))) %>% select(id) %>% unique()
运行结果
improving_students会返回id=1的学生(他的成绩逐年提升或持平)worse_students会返回id=2的学生(他的成绩逐年下降或持平)
补充说明
lag(grade, default = first(grade))的作用是获取每个成绩的前一个值,第一行没有前一个值,用first(grade)填充,这样all()就能覆盖所有相邻的成绩对比。显式的arrange()是为了确保数据是按年份顺序排列的,避免因为数据顺序错误导致判断结果出错。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

