如何对R数据框中指定层级对应的向量值求和?
按指定类别汇总TOTAL列求和问题解决
问题描述
我有一个数据框,SITUATION列包含三种值:UNMET(未满足)、FULLY MET(完全满足)、PARTIALLY MET(部分满足)。需要对FULLY MET和PARTIALLY MET这两类的TOTAL列求和,不想额外创建新列区分“已满足”和“未满足”。
尝试的错误代码
SITUATION <- rep(c("UNMET", "FULLY MET", "PARTIALLY MET"),8) BLOCK <- rep( 1:8, each = 3, len = 24 ) TOTAL <- floor(runif(24, min=2, max=32)) df <- as.data.frame(cbind(SITUATION, BLOCK, TOTAL)) agg_df <- aggregate(df$TOTAL, by=list(grepl(c("FULLY MET", "PARTIALLY MET"), df$ATENDENCE)), FUN=sum)
报错信息
Error in aggregate.data.frame(as.data.frame(x), ...) :
arguments must have the same length
In addition: Warning message:
In grepl(c("FULLY MET", "PARTIALLY MET"), df$ATENDENCE) :
argument 'pattern' has length > 1 and only the first element will be used
错误原因分析
- 列名拼写错误:代码里的
df$ATENDENCE是笔误,实际应该是df$SITUATION,引用不存在的列导致后续逻辑出错; - grepl参数使用错误:
grepl的pattern参数不能直接传字符向量,它只会取第一个元素(仅匹配"FULLY MET"),无法同时匹配两个目标类别; - 数据类型问题:用
cbind创建的数据框会把所有列转成字符类型,TOTAL列是字符格式,直接求和会失败。
正确解决方案
方法1:base R的aggregate函数实现
# 修正TOTAL列的数据类型为数值型 df$TOTAL <- as.numeric(df$TOTAL) # 用%in%生成等长逻辑分组向量,直接汇总 agg_df <- aggregate(TOTAL ~ I(SITUATION %in% c("FULLY MET", "PARTIALLY MET")), data = df, FUN = sum) # 重命名列让结果更直观 colnames(agg_df) <- c("是否已满足", "TOTAL总和")
方法2:dplyr(tidyverse)语法实现
如果习惯用tidyverse生态,代码更简洁易读:
library(dplyr) df %>% mutate(TOTAL = as.numeric(TOTAL)) %>% group_by(是否已满足 = SITUATION %in% c("FULLY MET", "PARTIALLY MET")) %>% summarise(TOTAL总和 = sum(TOTAL))
补充:grepl的替代写法
如果一定要用grepl,可以把两个模式用|连接,效果和%in%一致:
agg_df <- aggregate(TOTAL ~ I(grepl("FULLY MET|PARTIALLY MET", SITUATION)), data = df, FUN = sum)
内容的提问来源于stack exchange,提问作者Kledson Lemes
相关产品推荐
相关产品推荐

