如何基于文本/因子列筛选去重,优先保留指定因子值的行?
问题解决:按Name去重并优先保留Status为B的行
需求与示例
我有一个包含Name列(存在重复名称)和Status列(可设为因子/字符型)的data frame。需求为:
- 对
Name列去重 - 若同一
Name的重复行中有Status为B的行则保留该行 - 若重复行的Status值相同,则任意保留其一
示例数据
Name Status 1. John A 2. John B 3. Sally A 4. Alex A 5. Sarah B 6. Joe A 7. Joe A 8. Sue B 9. Sue B
期望结果
1. John B 2. Sally A 3. Alex A 4. Sarah B 5. Joe A 6. Sue B
原代码问题分析
你尝试的代码中,错误出在排序逻辑:
你将Status的levels设为c("A", "B")后按Status排序,这会让A排在B的前面,导致!duplicated会先保留John的A行,而非目标的B行。
解决方案
不需要用循环,以下两种方法更高效简洁:
方法一:Base R实现
Name <- c("John","John","Sally","Alex", "Sarah", "Joe", "Joe", "Sue", "Sue") Status <- c('A', 'B', 'A', 'A', 'B', 'A', 'A', 'B', 'B') df_reddit <- data.frame(Name,Status) # 给Status设置优先级:B的优先级高于A df_reddit$priority <- ifelse(df_reddit$Status == "B", 2, 1) # 按Name分组,再按优先级降序排序,最后去重保留每组第一行 df_result <- df_reddit[order(df_reddit$Name, -df_reddit$priority),] df_result <- df_result[!duplicated(df_result$Name),] # 移除临时的priority列 df_result <- df_result[,c("Name", "Status")] print(df_result)
方法二:dplyr包实现(更简洁)
library(dplyr) df_result <- df_reddit %>% group_by(Name) %>% # 优先选择Status为B的行,若同组无B则选A;多行同状态时任意保留一行 slice_max(order_by = Status == "B", n = 1) %>% ungroup() print(df_result)
这里slice_max通过Status == "B"将B行标记为1、A行标记为0,每组取最大值对应的行,正好满足优先保留B的需求。
内容的提问来源于stack exchange,提问作者ThreatworkAnalyst
相关产品推荐
相关产品推荐

