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

如何用dplyr或Base R按条件筛选数据框的唯一行?

按concat分组保留grpRnk最小的行

先创建测试数据框:

test <- data.frame(concat = c(1.1,1.2,2.1,2.1,2.2,2.2,3.1,3.2),
                   grpRnk = c(1,1,3,2,3,2,4,4))

原始数据如下:

> test
  concat grpRnk
1    1.1      1
2    1.2      1
3    2.1      3
4    2.1      2
5    2.2      3
6    2.2      2
7    3.1      4
8    3.2      4

原来用test %>% distinct(concat, .keep_all = TRUE)会保留每组concat的第一行,导致2.1和2.2对应的grpRnk是3,不符合需求。我们需要每个concat只保留grpRnk最小的行,以下是两种实现方式:

dplyr 实现

可以用group_by分组后,通过slice_min直接提取每组最小的行,或者用filter筛选出等于最小值的行:

library(dplyr)

# 方法1:slice_min 提取每组最小行
test %>% 
  group_by(concat) %>% 
  slice_min(grpRnk, n = 1) %>% 
  ungroup()

# 方法2:filter 匹配最小值
test %>% 
  group_by(concat) %>% 
  filter(grpRnk == min(grpRnk)) %>% 
  ungroup()

两种方法都会得到相同结果:

# A tibble: 6 × 2
  concat grpRnk
   <dbl>  <dbl>
1    1.1      1
2    1.2      1
3    2.1      2
4    2.2      2
5    3.1      4
6    3.2      4

Base R 实现

可以用aggregate先找出每个concat对应的最小grpRnk,再合并回原数据;或者用split+lapply的方式逐组处理:

# 方法1:aggregate+merge 匹配最小值
min_rnk <- aggregate(grpRnk ~ concat, data = test, FUN = min)
result <- merge(test, min_rnk, by = c("concat", "grpRnk"))

# 方法2:split分组后筛选最小值行
result <- do.call(rbind, lapply(split(test, test$concat), function(x) {
  x[x$grpRnk == min(x$grpRnk), ]
}))
rownames(result) <- NULL # 重置行名

运行后得到的结果和dplyr方法完全一致。

内容的提问来源于stack exchange,提问作者Village.Idyot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:20:27