You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R tidyverse自定义规则处理数据框:按组优先保留val=1的行

问题描述

需要按自定义规则对数据框进行分组去重:按ID分组后每组仅保留一行,优先保留组内val=1的行;若组内没有val=1的行,则保留val最小的行。

数据示例

创建示例数据框的代码:

x = data.frame(ID=c("a", "a", 
                    "b", "b", 
                    "c", "c", 
                    "d", "d"),
               val=c(1, 2, 
                     0.5, 2,
                     1, 0.5,
                     5, 20))

数据框内容:

ID  val
1  a  1.0
2  a  2.0
3  b  0.5
4  b  2.0
5  c  1.0
6  c  0.5
7  d  5.0
8  d 20.0

已尝试的方法及问题

  • 按val排序后去重
x %>% group_by(ID) %>% arrange(val) %>% distinct(ID, .keep_all = T) %>% arrange(ID)

结果:

ID      val
1 a       1  
2 b       0.5
3 c       0.5
4 d       5  

问题:ID为c的组错误保留了val=0.5的行,未优先选择val=1的行。

  • 使用slice_min函数
x %>%
  group_by(ID) %>%
  slice_min(order_by = tibble(val != 1, val), n = 1, with_ties = FALSE) %>%
  ungroup()

结果及警告:

# A tibble: 3 × 2
  ID      val
  <chr> <dbl>
1 a         1
2 c         1
3 d         5
Warning messages:
1: In xtfrm.data.frame(x) : cannot xtfrm data frames
2: In xtfrm.data.frame(x) : cannot xtfrm data frames
3: In xtfrm.data.frame(x) : cannot xtfrm data frames
4: In xtfrm.data.frame(x) : cannot xtfrm data frames

问题:丢失了ID为b的行,且出现无效警告。

期望输出

ID      val
1 a       1  
2 b       0.5
3 c       1
4 d       5  

解决方案

方法1:自定义排序后取首行

通过优先级排序,先把val=1的行排在每组最前面,再按val升序排序,最后每组取第一行:

library(dplyr)

x %>%
  group_by(ID) %>%
  arrange(desc(val == 1), val) %>%  # 优先val=1的行,再按val从小到大排序
  slice_head(n = 1) %>%
  ungroup() %>%
  arrange(ID)

方法2:分条件筛选合并

先提取所有val=1的行,再补充无val=1组的最小val行,最后合并排序:

library(dplyr)

# 提取所有val=1的行
val1_rows <- x %>% filter(val == 1)

# 提取无val=1的组,每组取val最小的行
min_val_rows <- x %>%
  anti_join(val1_rows, by = "ID") %>%
  group_by(ID) %>%
  slice_min(val, n = 1, with_ties = FALSE) %>%
  ungroup()

# 合并结果并按ID排序
bind_rows(val1_rows, min_val_rows) %>% arrange(ID)

两种方法均可得到符合要求的输出,且无异常警告。

内容的提问来源于stack exchange,提问作者Yan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:06:50