在R语言中按最大数值差10分组大数据集并统计数量与均值
问题:按值的接近程度分组(组内差值≤10)并统计数量与均值
需要编写R脚本,将数据框中cat1列的数值按组内所有值的差值小于10的规则分组,同时统计每组的数值数量和均值。注意不能直接按固定10区间分箱,需关注值之间的实际接近程度。
示例数据
cat1 = c(85, 60, 60, 55, 55, 15, 0, 35, 35 ) cat2 = c("a","a","a","a","a","a","a","a","a") df <- data.frame(cat1, cat2)
数据框内容:
cat1 cat2
1 85 a
2 60 a
3 60 a
4 55 a
5 55 a
6 15 a
7 0 a
8 35 a
9 35 a
期望输出
numValues cat1avg 1 85 4 57.5 1 15 1 0 2 35
解决方案:基于排序的贪心分组算法
核心思路是先对数值排序,再用贪心策略逐个将值加入当前组——若加入后组内最大值与最小值的差值超过10,则新建组。该方法效率高,适合批量处理大量小数据框。
完整代码
# 加载dplyr用于数据统计(若未安装先运行install.packages("dplyr")) library(dplyr) # 定义分组函数:按值的接近程度分组,组内最大差值不超过max_diff group_by_proximity <- function(x, max_diff = 10) { if (length(x) == 0) return(integer(0)) # 对数值排序并记录原始索引 sorted_x <- sort(x) sorted_idx <- order(x) # 初始化分组向量 groups <- integer(length(x)) current_group <- 1 groups[sorted_idx[1]] <- current_group current_min <- sorted_x[1] current_max <- sorted_x[1] # 遍历排序后的数值,分配分组 for (i in 2:length(sorted_x)) { val <- sorted_x[i] # 检查当前值是否能加入现有组 if (val - current_min <= max_diff && current_max - val <= max_diff) { groups[sorted_idx[i]] <- current_group # 更新组的最小/最大值 current_min <- min(current_min, val) current_max <- max(current_max, val) } else { # 新建分组 current_group <- current_group + 1 groups[sorted_idx[i]] <- current_group current_min <- val current_max <- val } } return(groups) } # 1. 为数据框添加分组列 df$group <- group_by_proximity(df$cat1) # 2. 统计每组的数量和均值 result <- df %>% group_by(group) %>% summarise( numValues = n(), cat1avg = mean(cat1) ) %>% select(-group) # 移除分组编号列 # 查看结果 print(result)
代码说明
group_by_proximity函数:接收数值向量和最大允许差值,返回每个元素对应的分组编号。通过排序+贪心遍历,确保每组内的所有值差值都不超过设定的阈值。- 批量处理:若需处理1000多个小数据框,可将上述流程封装为函数,结合循环批量执行,例如:
# 批量处理函数 process_df <- function(small_df) { small_df$group <- group_by_proximity(small_df$cat1) small_df %>% group_by(group) %>% summarise(numValues = n(), cat1avg = mean(cat1)) %>% select(-group) } # 假设df_list是包含所有小数据框的列表,批量处理 results_list <- lapply(df_list, process_df)
与固定区间分箱的区别
固定区间分箱(如cut函数)是按预设区间划分,而本方法是基于数值的实际分布动态分组:例如55和60差值为5,会被分到同一组;若后续加入61(与60差值1),仍会留在该组,直到加入某个值导致组内范围超过10时才新建组。
内容的提问来源于stack exchange,提问作者Becky Heath
相关产品推荐
相关产品推荐

