如何用R对数据集按月份进行Days条件计数聚合
解决R中按月份对Days字段进行条件区间聚合计数的问题
要实现按月份对Days字段进行多条件区间计数,我们可以用dplyr(tidyverse生态)或者data.table来完成,下面是两种具体的实现方案:
方法一:使用dplyr(适合熟悉tidyverse的用户)
首先加载dplyr包,然后按步骤处理:
library(dplyr) # 你的原始数据 df <- data.frame( 'Job Code' = c(1,1,8,9,1,1,2,3,4,2,3,4,5,6,7,5,6,7,2,3,4,8,4), 'Months' = c('Apr', 'May','Mar','Jan','Feb','Jun','Jul','Aug','Sep','Dec','Nov','Oct','Oct','Nov','Sep','Jun','Jul','Apr','Mar','May','Jan','Feb','Dec'), 'Days' = c(30,30,60,80,30,30,60,80,30,30,60,80,30,30,60,80,40,50,90,60,80,40,50) ) # 分组聚合+排序+添加总计行 result <- df %>% # 按月份分组 group_by(Months) %>% # 计算各区间的计数和当月总数 summarise( `<=30 days` = sum(Days <= 30), # 统计Days<=30的行数 `30 to 60 days` = sum(Days > 30 & Days <= 60), # 统计30<Days<=60的行数 `>60 days` = sum(Days > 60), # 统计Days>60的行数 Total = n() # 当月总记录数 ) %>% # 按自然月份顺序(Jan-Dec)排序,避免字母排序混乱 arrange(match(Months, month.abb)) %>% # 添加总计行,计算所有月份的汇总值 bind_rows( summarise(., Months = "Total", `<=30 days` = sum(`<=30 days`), `30 to 60 days` = sum(`30 to 60 days`), `>60 days` = sum(`>60 days`), Total = sum(Total) ) ) # 查看结果 print(result, row.names = FALSE)
执行后会得到你期望的输出格式,月份按自然顺序排列,且包含总计行。
方法二:使用data.table(适合大数据量场景)
如果你的数据量很大,data.table的效率会更高:
library(data.table) # 转换为data.table格式 setDT(df) # 分组聚合+排序 result_dt <- df[, .( `<=30 days` = sum(Days <= 30), `30 to 60 days` = sum(Days > 30 & Days <= 60), `>60 days` = sum(Days > 60), Total = .N # .N表示分组内的行数 ), by = Months][order(match(Months, month.abb))] # 添加总计行 result_dt <- rbind(result_dt, result_dt[, .( Months = "Total", `<=30 days` = sum(`<=30 days`), `30 to 60 days` = sum(`30 to 60 days`), `>60 days` = sum(`>60 days`), Total = sum(Total) )]) # 查看结果 print(result_dt, row.names = FALSE)
关键逻辑说明
- 条件计数:用
sum(逻辑条件)来实现,因为逻辑值TRUE会被当作1,FALSE当作0,求和就是符合条件的记录数。 - 月份排序:
match(Months, month.abb)会返回每个月份在内置月份缩写向量month.abb(Jan到Dec)中的位置,以此排序就能保证月份按自然顺序排列。 - 总计行:通过
bind_rows(dplyr)或rbind(data.table)添加汇总后的行,对各区间计数和总数分别求和。
内容的提问来源于stack exchange,提问作者Arun
相关产品推荐
相关产品推荐

