在R中为学生入学数据框追加指定汇总行的更优方法
优化R中追加合计行的实现方式
原始数据与需求
你的原始数据框定义如下:
df <- structure(list(Grade = c("PK3", "PK4", "KG", "Grade 1", "Grade 2", "Grade 3", "Grade 4", "Grade 5", "Grade 6", "Grade 7", "Grade 8", "Grade 9", "Grade 10", "Grade 11", "Grade 12", "Ungraded"), Enrolled = c(4967, 6481, 7378, 7041, 6760, 6590, 6473, 6191, 5790, 5693, 5614, 7254, 4951, 4250, 3792, 238)), row.names = c(NA, -16L), class = c("tbl_df", "tbl", "data.frame"))
需求是在数据框末尾追加两行:
k_12_total:K-12年级(排除PK3、PK4)的总入学人数pk_12_total:PK-12年级(所有行)的总入学人数
你当前的实现(冗长版)
df2 = df %>% filter(Grade != "PK3" & Grade != "PK4") %>% adorn_totals(where="row", name="k_12_total") %>% filter(Grade == "k_12_total") df = rbind(df, df2) df2 = df %>% filter(Grade != "k_12_total") %>% adorn_totals(where="row", name="pk_12_total") %>% filter(Grade == "pk_12_total") df = rbind(df, df2)
更优的实现方式
方法1:用dplyr直接计算+一次性合并
直接生成两个合计行,再用bind_rows合并,避免多次修改原数据框:
library(dplyr) # 生成K-12合计行 k12_total <- df %>% filter(!Grade %in% c("PK3", "PK4")) %>% summarize(Grade = "k_12_total", Enrolled = sum(Enrolled)) # 生成PK-12合计行 pk12_total <- df %>% summarize(Grade = "pk_12_total", Enrolled = sum(Enrolled)) # 合并所有数据 df_final <- bind_rows(df, k12_total, pk12_total)
方法2:用janitor简化取合计行的操作
如果坚持用janitor包,可以用slice_tail直接取最后一行的合计,替代filter:
library(janitor) library(dplyr) k12_total <- df %>% filter(!Grade %in% c("PK3", "PK4")) %>% adorn_totals("row", name = "k_12_total") %>% slice_tail(n = 1) pk12_total <- df %>% adorn_totals("row", name = "pk_12_total") %>% slice_tail(n = 1) df_final <- bind_rows(df, k12_total, pk12_total)
方法3:最紧凑的链式写法
不需要单独创建中间变量,直接在bind_rows里完成两个合计的计算:
library(dplyr) df_final <- df %>% bind_rows( # 计算K-12合计 summarize(., Grade = "k_12_total", Enrolled = sum(Enrolled[!Grade %in% c("PK3", "PK4")])), # 计算PK-12合计 summarize(., Grade = "pk_12_total", Enrolled = sum(Enrolled)) )
以上三种方法都比你原来的代码更简洁直观,避免了重复的filter和rbind操作,同时保持逻辑清晰。
内容的提问来源于stack exchange,提问作者user3710004
相关产品推荐
相关产品推荐

