基于Iris数据集按物种与年份分组筛选最大观测数年份(含重复最大值)
嘿,我来帮你搞定这个Iris数据集的分组筛选问题,包括处理观测数最大值重复的情况~
解决方案:为Iris数据集筛选各物种观测数最多的年份
我们一步步来实现需求,从构造数据集到完成筛选,同时处理重复最大值的场景。
1. 先构造带Year列的Iris数据集
首先运行你提供的代码,给原始Iris数据集添加Year列:
# 为Iris数据集添加Year列 iris$Year <- c(rep(c("2007", "2008"), each = 25), rep(c("2007", "2008"), times = c(10, 40)), rep(c("2007", "2008"), times = c(40, 10)))
这段代码的分配逻辑很清晰:
- setosa物种:2007和2008年各25条观测
- versicolor物种:2007年10条,2008年40条
- virginica物种:2007年40条,2008年10条
2. 分组统计+筛选目标年份
接下来我们要按Species和Year分组统计观测数,然后为每个物种选出观测数最多的年份。这里重点处理**某物种存在多个年份观测数相同(比如setosa的两年都是25条)**的情况。
方法1:用dplyr包(语法更直观)
如果你习惯用tidyverse系列的包,dplyr的写法会很清晰:
library(dplyr) # 完成分组统计与筛选 result <- iris %>% # 按物种、年份分组,统计每组的观测数量 group_by(Species, Year) %>% summarise(count = n(), .groups = "drop_last") %>% # 筛选出每个物种中观测数最大的行 filter(count == max(count)) %>% # 可选:如果要处理重复最大值(比如setosa的两年),可以按规则保留一个 # slice_min(Year) # 取消注释即可保留最早年份;选最晚年份用slice_max(Year) ungroup() # 查看最终结果 print(result)
默认运行后,setosa会返回2007和2008两行(因为观测数都是25),versicolor返回2008年(40条),virginica返回2007年(40条)。如果想在重复时只保留一个年份,取消对应注释即可。
方法2:用基础R(无需额外安装包)
如果不想加载第三方包,用基础R也能实现同样的逻辑:
# 先统计每个物种-年份组合的观测数 count_df <- table(iris$Species, iris$Year) %>% as.data.frame(responseName = "count") %>% setNames(c("Species", "Year", "count")) # 按物种分组,筛选出观测数最大的行 result_base <- do.call(rbind, lapply(split(count_df, count_df$Species), function(df) { df[df$count == max(df$count), ] })) # 可选:处理重复最大值,比如只保留每个物种的最早年份 # result_base <- do.call(rbind, lapply(split(count_df, count_df$Species), function(df) { # df_sorted <- df[order(df$Year), ] # df_sorted[df_sorted$count == max(df_sorted$count), ][1, ] # })) # 清理行名,让结果更整洁 rownames(result_base) <- NULL print(result_base)
这个版本的逻辑和dplyr完全一致,默认保留所有达到最大值的年份,注释部分是处理重复时只保留最早年份的写法。
关键逻辑说明
- 核心步骤是先按
Species和Year分组统计观测数,这是后续筛选的基础 - 处理重复最大值时,有两种常见思路:
- 保留所有观测数达到最大值的年份(适合需要展示所有峰值的场景)
- 按规则选择其中一个(比如最早/最晚年份、随机选择,适合需要唯一结果的场景)
你可以根据实际需求调整代码中的筛选步骤。
内容的提问来源于stack exchange,提问作者B. Davis
相关产品推荐
相关产品推荐

