使用dplyr::distinct(.keep_all=TRUE)时如何指定保留特定行?
解决dplyr去重时指定保留目标行的问题
首先定义测试数据框:
df <- data.frame( x = c("A", "A", "A"), y = c(1, 0, 1), z = c("o", "m", "g") )
方法1:排序后用distinct(最直观)
通过排序让你想要保留的行在每组x,y中排在最前面,调用distinct时就会优先保留该行:
library(dplyr) df %>% arrange(x, y, desc(z == "g")) %>% # 让z='g'的行在同x,y组中排第一 distinct(across(-z), .keep_all = TRUE)
输出结果:
x y z 1 A 0 m 2 A 1 g
方法2:分组后筛选目标行
按x,y分组,直接筛选组内符合z=='g'的行;如果组内没有符合条件的行,就保留第一行作为兜底:
df %>% group_by(x, y) %>% filter(z == "g" | row_number() == 1) %>% ungroup()
方法3:用slice_max选择权重最高的行
给目标行设置更高权重,用slice_max提取每组中权重最高的行:
df %>% group_by(x, y) %>% slice_max(order_by = (z == "g"), n = 1) %>% # z=='g'时权重为1,其他为0 ungroup()
扩展:指定多个目标值的优先级
如果需要保留多个z值且有优先级(比如优先g,其次m),可以给z值设置优先级排序:
# 定义优先级顺序,越靠前优先级越高 z_priority <- c("g", "m", "o") df %>% mutate(priority = match(z, z_priority)) %>% # 给每个z值分配优先级数值 arrange(x, y, priority) %>% distinct(across(-c(z, priority)), .keep_all = TRUE) %>% select(-priority) # 移除临时优先级列
内容的提问来源于stack exchange,提问作者FISR
相关产品推荐
相关产品推荐

