R语言按年月、国家分组计算字段最大最小值实现方法
问题描述
现有如下结构的R数据框,需要按国家、年份、月份维度分组,分别计算每组Amount字段的最大值和最小值,输出包含Country/Year/Month/Max/Min五列的汇总表。
测试数据构造代码:
Date <- c("2004-01-01","2004-01-01", "2004-01-15","2004-01-26","2004-02-01","2004-02-03","2004-02-03","2004-02-03","2004-03-01","2004-03-02","2004-03-02","2004-03-06","2004-03-06","2004-03-10", "2004-03-11","2004-03-11","2004-03-12","2004-03-12", "2004-01-01","2004-01-01", "2004-01-15","2004-01-26","2004-02-01","2004-02-03","2004-02-03","2004-02-03","2004-03-01","2004-03-02","2004-03-02","2004-03-06","2004-03-06","2004-03-10", "2004-03-11","2004-03-11","2004-03-12","2004-03-12", "2004-01-01","2004-01-01", "2004-01-15","2004-01-26","2004-02-01","2004-02-03","2004-02-03","2004-02-03","2004-03-01","2004-03-02","2004-03-02","2004-03-06","2004-03-06","2004-03-10","2004-03-11","2004-03-11","2004-03-12","2004-03-12") Country <- c("Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands", "Netherlands","Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "France", "France", "France","France", "France", "France","France", "France", "France","France", "France", "France","France", "France", "France","France", "France", "France") Year <- c(2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004, 2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004,2004) Month <- c(1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,1, 1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3) Amount <- as.numeric(c(100,50,40,3.50,14.60,11.60,140.20,140.30,147.30,151.20,159.60, 165.60,173.20,177.30,185.30,199.30,217.10,234.90,10.20,3.10,16.00,4.90,17.60,5.30,10.90,12.80,8.40,140.20,140.30,147.30,151.20,159.60,165.60,173.20,177,40,50,.30,185.30,199.30,217.10,234.9,500,300,0,8.40,140.20,140.30,3,147.30,151.20,8,40,30)) df <- data.frame(as.Date(Date),Country,Year, Month, Amount)
之前使用如下代码测试,始终返回全数据集的最大最小值,无法得到分组统计结果:
df %>% group_by(Country,Month) %>% summarise(MaxAmount = max(Amount, na.rm = T), MinAmount = min(Amount, na.rm = T))
故障原因
分组统计失效主要有两个原因:
- 函数命名冲突:如果同时加载了
plyr和dplyr包,且没有按顺序加载,会导致group_by、summarise函数调用错误,分组逻辑不生效 - 分组字段不全:代码中只按
Country和Month分组,漏了Year字段,跨年数据会出现统计错误;另外给出的期望示例表存在两处错误:一是所有年份误写为2014,实际数据均为2004年;二是Netherlands2月、3月的最大最小值写反了。
正确实现代码
通过显式指定dplyr包前缀调用函数,彻底避免命名冲突,同时补全分组字段:
library(dplyr) result <- df %>% dplyr::group_by(Country, Year, Month) %>% dplyr::summarise( Max = max(Amount, na.rm = TRUE), Min = min(Amount, na.rm = TRUE), .groups = "drop" # 统计完成后自动取消分组,不影响后续数据操作 )
运行后得到的正确统计结果如下:
| Country | Year | Month | Max | Min |
|---|---|---|---|---|
| Netherlands | 2004 | 1 | 100.0 | 3.5 |
| Netherlands | 2004 | 2 | 140.3 | 11.6 |
| Netherlands | 2004 | 3 | 234.9 | 147.3 |
| Belgium | 2004 | 1 | 16.0 | 3.1 |
| Belgium | 2004 | 2 | 17.6 | 5.3 |
| Belgium | 2004 | 3 | 177.0 | 8.4 |
| France | 2004 | 1 | 199.3 | 0.3 |
| France | 2004 | 2 | 500.0 | 217.1 |
| France | 2004 | 3 | 151.2 | 0.0 |
小提示:如果需要同时使用
plyr和dplyr,一定要先加载plyr再加载dplyr,否则就全程用dplyr::前缀调用函数,就不会出现分组失效的问题。
内容的提问来源于stack exchange,提问作者Zuzana
相关产品推荐
相关产品推荐

