如何按id和type获取min_price最值并保留所有列?
按id和type分组筛选min_price极值对应的完整行
嗨,我来帮你搞定这个问题!首先先重现你的数据集:
library(tibble) df_A <- tribble( ~id, ~type, ~min_price, ~max_price, "1", "X", 10, 40, "1", "Y", 20, 50, "1", NA, 15, 70, "2", "X", 40, 90, "2", "Y", 23, 100, )
你的需求是按id和type分组,筛选出每组里min_price取最小值和最大值的完整行——确实用summarise会丢掉原有列,而mutate写起来又啰嗦,其实dplyr里有更简洁的解决方案,给你两种常用方法:
方法1:用slice_min() + slice_max()(直观简洁)
dplyr的slice_min()和slice_max()专门用来提取分组后某列极值对应的行,而且会保留所有列:
library(dplyr) result <- df_A %>% # 按id和type分组 group_by(id, type) %>% # 提取每组min_price最小的行 slice_min(min_price, n = 1, na.rm = TRUE) %>% # 和每组min_price最大的行合并 bind_rows( df_A %>% group_by(id, type) %>% slice_max(min_price, n = 1, na.rm = TRUE) ) %>% # 按id和type排序,方便查看结果 arrange(id, type) %>% ungroup() # 可选:取消分组,回到普通数据框
- 注意加
na.rm = TRUE是因为你的数据里有type为NA的组,避免极值计算返回NA导致筛选失败; - 如果某组里
min_price的极值有多个重复值,把n=1改成with_ties=TRUE就能保留所有重复的极值行。
方法2:用filter()直接判断(灵活通用)
如果你更习惯用filter逻辑,也可以直接判断当前行的min_price是否等于组内的最小值或最大值:
result <- df_A %>% group_by(id, type) %>% filter( min_price == min(min_price, na.rm = TRUE) | min_price == max(min_price, na.rm = TRUE) ) %>% ungroup()
这种方法会自动保留所有符合条件的行(包括重复极值),逻辑更直白,适合需要扩展筛选条件的场景。
两种方法都能完美保留max_price等所有原有列,你可以根据自己的习惯选择~
内容的提问来源于stack exchange,提问作者datazang




