You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中对ID-gene组合去重并保留指定status的行

按ID-gene组合筛选优先保留Positive状态行的解决方案

针对你处理超20万行、含26000个ID的大型data frame的需求——每个ID-gene组合优先保留Positive状态的行,仅当无Positive时保留一条Negative行,这里有两种高效的实现方式:

方法一:用dplyr(推荐,代码简洁高效)

dplyr的分组操作非常适合这类需求,代码可读性强,处理大数据量也很高效:

首先补全你的示例数据构造代码(原代码缺失ID向量):

ID <- c("1001A", "1001A", "1001A", "1001A", "1002B", "1002B", "1002B")
gene <- c('Gene 1', "Gene 2", "Gene 1", "Gene 1", "Gene 1", "Gene 1", "Gene 1")
status <- c("Negative", "Negative", "Positive", "Negative", "Negative", "Negative", "Negative")
df <- data.frame(ID, gene, status, stringsAsFactors = FALSE)
# 按需求将status转为因子类型
df$status <- factor(df$status, levels = c("Negative", "Positive"))

然后执行筛选逻辑:

library(dplyr)

filtered_df <- df %>%
  # 按ID和gene的组合分组
  group_by(ID, gene) %>%
  # 按status降序排序,让Positive排在每组最前面(因为因子水平Negative在前,降序后Positive优先)
  arrange(desc(status)) %>%
  # 取每组的第一行
  slice_head(n = 1) %>%
  # 取消分组状态
  ungroup()

# 查看结果
print(filtered_df)

输出结果完全匹配你的示例要求:

# A tibble: 3 × 3
  ID    gene   status
  <chr> <chr>  <fct> 
1 1001A Gene 1 Positive
2 1001A Gene 2 Negative
3 1002B Gene 1 Negative

方法二:Base R实现(无需加载额外包)

如果不想加载dplyr包,用Base R也能实现需求:

# 先给状态赋值权重:Positive为2,Negative为1
df$weight <- ifelse(df$status == "Positive", 2, 1)

# 按ID-gene分组,筛选出每组中权重最大的行
temp_df <- df[with(df, ave(weight, ID, gene, FUN = function(x) x == max(x))), ]
# 去重(避免同一ID-gene组合有多个Positive时保留多行)
filtered_df_base <- temp_df[!duplicated(temp_df[c("ID", "gene")]), ]
# 移除临时的weight列
filtered_df_base <- filtered_df_base[, !names(filtered_df_base) %in% "weight"]

# 查看结果
print(filtered_df_base)

补充说明

  • 对于你的大数据量,dplyr的方法在效率上更有优势,若需要极致性能还可以搭配data.table的分组操作进一步提速;
  • 确保status因子的水平设置正确,如果你的因子水平是c("Positive", "Negative"),排序时直接用arrange(status)即可,无需降序。

内容的提问来源于stack exchange,提问作者user305007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:40:06