基于最大值与第二大值的差值筛选DataFrame分组
基于最大值与第二大值的差值筛选DataFrame分组
问题描述
现有如下R DataFrame df:
> df group value 1 A 5 2 A 1 3 A 1 4 A 5 5 B 8 6 B 2 7 B 2 8 B 3 9 C 10 10 C 1 11 C 1 12 C 8
df的dput代码:
df<-structure(list(group = c("A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C"), value = c(5, 1, 1, 5, 8, 2, 2, 3, 10, 1, 1, 8)), class = "data.frame", row.names = c(NA, -12L))
需求:根据每组最大值与第二大值的差值筛选分组,仅保留差值≤2的分组。例如B组最大值8,第二大值3,差值5,需被移除,最终期望输出:
group value 1 A 5 2 A 1 3 A 1 4 A 5 5 C 10 6 C 1 7 C 1 8 C 8
解决方案
方法1:使用dplyr包(tidyverse风格)
通过分组计算临时差值,筛选符合条件的分组后清理临时列:
library(dplyr) df %>% group_by(group) %>% mutate( # 提取每组去重后降序排列的数值列表 unique_vals = list(sort(unique(value), decreasing = TRUE)), # 计算最大值与第二大值的差值,单值组差值设为0 diff_max = ifelse(length(unique_vals[[1]]) >= 2, unique_vals[[1]][1] - unique_vals[[1]][2], 0) ) %>% filter(diff_max <= 2) %>% select(-unique_vals, -diff_max) %>% ungroup()
方法2:使用base R
先计算每组的差值,再筛选原数据中符合条件的分组:
# 按分组计算最大值与第二大值的差值 group_diff <- tapply(df$value, df$group, function(x) { sorted_unique <- sort(unique(x), decreasing = TRUE) if (length(sorted_unique) >= 2) sorted_unique[1] - sorted_unique[2] else 0 }) # 筛选出差值≤2的分组 valid_groups <- names(group_diff[group_diff <= 2]) # 提取原数据中符合条件的行 df[df$group %in% valid_groups, ]
两种方法均可得到目标输出,若分组内所有值相同(仅一个唯一值),差值为0会被自动保留。
内容的提问来源于stack exchange,提问作者Quinten
相关产品推荐
相关产品推荐

