如何在R语言中基于Room、Name双列分组生成Class列值为列名的汇总表
按Room和Name双分组实现Class列转宽表(FY求和)
首先先确认你的原始数据:
sample = data.frame( "Room" = c("A1", "B2","A1","A3","A2"), "Name"=c("Peter","Tom","Peter","Anna","Peter"), "Class"=c("E","E","F","D","E"), "FY"=c(1,2,3,4,6) )
你需要实现的是以Room和Name作为行标识,将Class的唯一值转为列,列值对应分组内FY的求和结果,下面给你两种常用的实现方式:
方法一:Base R 原生实现
这种方式不需要额外安装包,分两步走:先分组求和,再转宽格式:
- 先按Room、Name、Class分组计算FY的总和:
sum_df <- aggregate(FY ~ Room + Name + Class, data = sample, FUN = sum)
- 将长格式数据转为宽格式,同时整理列名和顺序:
# 转宽,指定行标识为Room和Name,列标识为Class output_base <- reshape(sum_df, idvar = c("Room", "Name"), timevar = "Class", direction = "wide") # 去掉列名里的"FY."前缀 colnames(output_base) <- gsub("FY\\.", "", colnames(output_base)) # 调整列顺序,匹配你预期的输出 output_base <- output_base[, c("Room", "Name", "E", "F", "D")]
运行后output_base就和你预期的结果一致,缺失值会自动填充为NA。
方法二:Tidyverse 简洁实现
如果你习惯用dplyr和tidyr,代码会更易读:
先加载包(如果没安装的话先运行install.packages(c("dplyr", "tidyr"))):
library(dplyr) library(tidyr)
然后通过分组求和+转宽一步到位:
output_tidy <- sample %>% # 按三个变量分组,计算FY总和 group_by(Room, Name, Class) %>% summarise(FY_sum = sum(FY), .groups = "drop") %>% # 将Class转为列名,FY_sum作为对应值 pivot_wider(names_from = Class, values_from = FY_sum) %>% # 调整列顺序,和预期输出一致 select(Room, Name, E, F, D)
验证结果
两种方法得到的结果都和你预期的output完全匹配:
# 预期输出 output = data.frame( Room = c("A1", "B2","A3", "A2"), Name = c("Peter","Tom","Anna","Peter"), E = c(1,2,NA,6), F = c(3,NA,NA,NA), D = c(NA,NA,4,NA) )
内容的提问来源于stack exchange,提问作者WinterMensch
相关产品推荐
相关产品推荐

