R语言多分组场景下计算同科目相邻年份相邻层级学生人数差值
解决方案
实现逻辑
- 升学匹配仅在同一科目下生效,因此仅需按
Subject字段分组 - 分组后按年份升序排序,保证
lag()函数可以正确提取上一年的对应数据 - 仅对高年级(示例数据中为Level=21)计算差值:差值 = 上一年同科目低年级(Level=20)人数 - 本年同科目高年级人数,低年级行的差值统一设为NA
可运行代码
library(dplyr) # 注意:原变量名rep为R内置函数名,建议重命名为df避免冲突 df <- structure(list(Year = c(2005L, 2005L, 2005L, 2005L, 2005L, 2005L, 2006L, 2006L, 2006L, 2006L, 2006L, 2006L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2008L, 2008L), Subject = c("Englisch", "Englisch", "GK", "GK", "Mathematik", "Mathematik", "Englisch", "Englisch", "GK", "GK", "Mathematik", "Mathematik", "Englisch", "Englisch", "GK", "GK", "Mathematik", "Mathematik", "Englisch", "Englisch"), Level = c(20L, 21L, 20L, 21L, 20L, 21L, 20L, 21L, 20L, 21L, 20L, 21L, 20L, 21L, 20L, 21L, 20L, 21L, 20L, 21L), Students = c(27104L, 24841L, 29945L, 2862L, 29907L, 27802L, 28837L, 26357L, 31815L, 2880L, 31721L, 29115L, 30324L, 28064L, 32924L, 3508L, 32862L, 30862L, 32124L, 29624L)), row.names = c(NA, -20L), groups = structure(list(Year = c(2005L, 2005L, 2005L, 2006L, 2006L, 2006L, 2007L, 2007L, 2007L, 2008L), Subject = c("Englisch", "GK", "Mathematik", "Englisch", "GK", "Mathematik", "Englisch", "GK", "Mathematik", "Englisch"), .rows = structure(list(1:2, 3:4, 5:6, 7:8, 9:10, 11:12, 13:14, 15:16, 17:18, 19:20), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", "tbl_df", "tbl", "data.frame")) result <- df %>% arrange(Subject, Year) %>% group_by(Subject) %>% mutate( # 提取上一年同科目Level=20的学生人数 prev_low_stu = lag(Students[Level == 20], n = 1), # 仅Level=21的行计算差值 Difference = ifelse(Level == 21, prev_low_stu - Students, NA) ) %>% select(-prev_low_stu) %>% ungroup()
如果你的Level字段取值为1和2,只需要把代码中的Level == 20替换为Level == 1,Level == 21替换为Level == 2即可通用。
结果验证
以示例数据中的英语科目为例:
2005年Level=20的学生人数为27104,2006年Level=21的学生人数为26357,计算得到的差值为27104 - 26357 = 747,符合需求逻辑。
内容的提问来源于stack exchange,提问作者SamVimes
相关产品推荐
相关产品推荐

