如何按grade优先级(2 > -8 > 1)在每个ID分组中保留目标行?
按自定义Grade优先级分组保留最高优先级行的实现方法
需求:对数据框df1按ID列分组,按照grade列的自定义优先级规则(2 > -8 > 1),保留每组中符合最高优先级grade值的行。
示例输入数据
> df1 ID grade col1 col2 1 AMM115 2 1 23 2 AMM115 1 1 23 3 AMM115 2 1 23 4 AGM132 -8 2 24 5 AGM132 1 2 24 6 ARM028 -8 1 28 7 ASM019 -8 2 17 8 AHM172 -8 2 63 9 ARM028 2 1 28 10 AHM172 2 2 63
期望输出结果
> df2 ID grade col1 col2 1 AMM115 2 1 23 4 AGM132 -8 2 24 7 ASM019 -8 2 17 9 ARM028 2 1 28 10 AHM172 2 2 63
实现方法
方法1:使用dplyr包(推荐)
通过将grade转换为有序因子,自定义优先级顺序,再分组筛选最高优先级的行:
library(dplyr) # 定义grade的优先级顺序 grade_priority <- c(2, -8, 1) df2 <- df1 %>% # 将grade转为有序因子,指定优先级顺序 mutate(grade = factor(grade, levels = grade_priority, ordered = TRUE)) %>% group_by(ID) %>% # 筛选每组中优先级最高的grade行 filter(grade == max(grade)) %>% # 若同一组有多个最高优先级行,保留第一行(匹配示例结果) slice_head(n = 1) %>% # 将grade转回整数类型 mutate(grade = as.integer(as.character(grade))) %>% ungroup() # 查看结果 df2
方法2:使用Base R
通过给不同grade分配优先级权重,分组筛选权重最高的行:
# 定义优先级权重:优先级越高,权重值越大 priority_weights <- c("2" = 3, "-8" = 2, "1" = 1) df1$weight <- priority_weights[as.character(df1$grade)] # 按ID分组,提取每组中权重最高的第一行 df2 <- do.call(rbind, lapply(split(df1, df1$ID), function(group) { max_weight <- max(group$weight) group[group$weight == max_weight, ][1, ] })) # 移除临时的weight列 df2 <- df2[, names(df2) != "weight"] # 查看结果 df2
内容的提问来源于stack exchange,提问作者Roq
相关产品推荐
相关产品推荐

