如何按x2分组选取对应z列最大值且同x1的所有行?
R语言分组筛选问题
数据生成
set.seed(2024) df <- data.frame(x1=rep(c(1:4),each=12), x2=rep(c("A","B","C"),each=4,times=4), y=runif(48), z=rep(c(12,4,19,8,58,2,33,32,25,70,5,25),each=4))
筛选需求
按x2的唯一值分组,执行以下筛选逻辑:
- 每组选取
z列值最大的对应行; - 若同一分组内
z的最大值对应多个x1值,则选取其中x1最小的那组所有行。
分组示例
- A组:z最大值为70,对应x1=4,需选中x1=4的所有行:
37 4 A 0.0541251726 70 38 4 A 0.9661198864 70 39 4 A 0.0221378489 70 40 4 A 0.6473674888 70
- B组:z最大值为58,对应x1=2,需选中x1=2的所有行:
17 2 B 0.1103110805 58 18 2 B 0.8632152062 58 19 2 B 0.1310691827 58 20 2 B 0.2954267922 58
- C组:z最大值为25,对应x1=3和x1=4,需选中x1最小的x1=3的所有行:
33 3 C 0.1762014020 25 34 3 C 0.9733794478 25 35 3 C 0.6751627198 25 36 3 C 0.6809547509 25
预期结果
x1 x2 y z 37 4 A 0.0541251726 70 38 4 A 0.9661198864 70 39 4 A 0.0221378489 70 40 4 A 0.6473674888 70 17 2 B 0.1103110805 58 18 2 B 0.8632152062 58 19 2 B 0.1310691827 58 20 2 B 0.2954267922 58 33 3 C 0.1762014020 25 34 3 C 0.9733794478 25 35 3 C 0.6751627198 25 36 3 C 0.6809547509 25
现有代码问题
当前使用的代码仅能返回每组的单行,无法选中同一x1对应的所有行:
library(dplyr) df %>% group_by(x2) %>% slice(which.max(z))
解决方案
方法一:分步筛选
通过临时列标记最大值和最小x1,再进行筛选:
library(dplyr) df %>% group_by(x2) %>% # 标记当前组的z最大值 mutate(max_z = max(z)) %>% # 筛选出z等于最大值的行 filter(z == max_z) %>% # 标记当前筛选结果中的最小x1 mutate(min_x1 = min(x1)) %>% # 保留x1等于最小x1的所有行 filter(x1 == min_x1) %>% # 移除临时辅助列 select(-max_z, -min_x1) %>% ungroup()
方法二:简洁写法
利用slice_min的n=Inf参数保留所有符合条件的行:
library(dplyr) df %>% group_by(x2) %>% # 先筛选z为当前组最大值的行 filter(z == max(z)) %>% # 在筛选结果中选取x1最小的所有行 slice_min(x1, n = Inf) %>% ungroup()
以上两种方法均可得到符合预期的筛选结果。
内容的提问来源于stack exchange,提问作者HappyPy
相关产品推荐
相关产品推荐

